web-dev-qa-db-ja.com

Django Rest Frameworkカスタム認証

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

Djangoアプリでカスタム認証を使用したいが、これを適用する方法が見つからないこの新しいクラスを作成し、これを使用する方法。

前もって感謝します!

13
Arbaz Rizvi

DRFにカスタム認証方式を実装する方法

カスタム認証スキームを実装するには、DRFのBaseAuthenticationクラスをサブクラス化し、.authenticate(self, request)メソッドをオーバーライドする必要があります。

このメソッドは、認証が成功した場合は_(user, auth)_の2つのタプルを返し、そうでない場合はNoneを返す必要があります。状況によっては、.authenticate()メソッドからAuthenticationFailed例外が発生する場合があります。

例( DRF docs から):

_'X_USERNAME'_という名前のカスタムリクエストヘッダーのusernameで指定されたユーザーとして、すべての着信リクエストを認証するとします。

ステップ-1:カスタム認証クラスを作成します

そのために、_authentication.py_に_my_app_ファイルを作成します。

_# 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

    ...
_
13
Rahul Gupta

以下は、カスタム認証を実現するために使用できる簡単な例です。エンドポイントにアクセスするには、POSTデータのユーザー名とパスワードを渡す必要があります。

rls.py

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

views.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'
5
Slipstream

私は次の方法を使用しました

from rest_framework_jwt.settings import api_settings
from rest_framework import status, generics

 class UserLogin(generics.CreateAPIView):

    def post(self, request, *args, **kwargs):
        email = request.data['email']
        if email is None:
            return Response({'error': 'Email not informed'}, status=status.HTTP_403_FORBIDDEN)
        try:
            user = User.objects.get(email=email)
            if not user.check_password(request.data['password']):
                return Response({'error': 'Email ou senha incorreto'}, status=status.HTTP_400_BAD_REQUEST)
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return Response({"token": token, "user":UserSessionSerializerAuth(user,
                        context={'request': request}).data}, status=status.HTTP_200_OK)
        except User.DoesNotExist:
            return Response({'error': 'User not found'}, status=status.HTTP_403_FORBIDDEN)
0
Antonio Junior

APIファイルを保持するフォルダーに、authentication.pyなどのカスタム認証クラスを保持する別のファイルを作成します。次に、設定の DEFAULT_AUTHENTICATION_CLASSES で、カスタム認証クラスをポイントします。

0
mcastle