Django Rest框架自定义身份验证

2024-04-18 10:26:34 发布

您现在位置:Python中文网/ 问答频道 /正文

http://www.django-rest-framework.org/api-guide/authentication/#custom-authentication

我想在我的django应用程序中使用自定义身份验证,但找不到如何应用此功能。有人能帮我做这个吗。文档中给出的示例对我来说很清楚,但他们没有提到在何处创建这个新类以及如何使用它。

提前谢谢!


Tags: django文档org功能身份验证restapi应用程序
3条回答

如何在DRF中实现自定义身份验证方案?

要实现自定义身份验证方案,我们需要对DRF的BaseAuthentication类进行子类化并重写.authenticate(self, request)方法。

如果身份验证成功,该方法应返回两个元组(user, auth),否则返回None。在某些情况下,我们可能会从.authenticate()方法引发AuthenticationFailed异常。

示例(来自DRF docs):

假设我们要将任何传入请求验证为名为'X_USERNAME'的自定义请求头中username给定的用户。

步骤1:创建自定义身份验证类

为此,我们将在my_app中创建一个authentication.py文件。

# my_app/authentication.py
from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions

class ExampleAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        username = request.META.get('X_USERNAME') # get the username request header
        if not username: # no username passed in request headers
            return None # authentication did not succeed

        try:
            user = User.objects.get(username=username) # get the user
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed('No such user') # raise exception if user does not exist 

        return (user, None) # authentication successful

步骤2:指定自定义身份验证类

创建自定义身份验证类之后,我们需要在DRF设置中定义该身份验证类。这样,所有请求都将基于此身份验证方案进行身份验证。

'DEFAULT_AUTHENTICATION_CLASSES': (       
    'my_app.authentication.ExampleAuthentication', # custom authentication class
    ...
),

注意:如果要在每个视图或每个视图集的基础上而不是在全局级别上使用此自定义身份验证类,则可以在视图中显式定义此身份验证类。

class MyView(APIView):

    authentication_classes = (ExampleAuthentication,) # specify this authentication class in your view

    ...

在保存api文件的文件夹中,创建另一个文件来保存自定义身份验证类,例如authentication.py。然后在您的设置中,在DEFAULT_AUTHENTICATION_CLASSES下,指向您的自定义身份验证类。

下面是一个可用于实现自定义身份验证的简单示例。要访问端点,必须在POST数据上传递用户名和密码。

url.py

urlpatterns = [
    url(r'^stuff/', views.MyView.as_view()),
    ...
]

视图.py

    from django.contrib.auth.models import User
    from rest_framework import viewsets
    from rest_framework.response import Response
    from rest_framework.views import APIView    
    from rest_framework.permissions import IsAuthenticated
    from rest_framework import exceptions
    from rest_framework import authentication
    from django.contrib.auth import authenticate, get_user_model
    from rest_framework.authentication import BasicAuthentication, 
SessionAuthentication


class ExampleAuthentication(authentication.BaseAuthentication):

    def authenticate(self, request):

        # Get the username and password
        username = request.data.get('username', None)
        password = request.data.get('password', None)

        if not username or not password:
            raise exceptions.AuthenticationFailed(_('No credentials provided.'))

        credentials = {
            get_user_model().USERNAME_FIELD: username,
            'password': password
        }

        user = authenticate(**credentials)

        if user is None:
            raise exceptions.AuthenticationFailed(_('Invalid username/password.'))

        if not user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))


    return (user, None)  # authentication successful


class MyView(APIView):
    authentication_classes = (SessionAuthentication, ExampleAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):    
        content = {
            'user': unicode(request.user),
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

卷曲

curl -v -X POST http://localhost:8000/stuff/ -d 'username=my_username&password=my_password'

相关问题 更多 >