Django REST_framework 認證類

認證類django

APIView -> dispatch -> self.initial -> self.perform_authenticationapp

    def perform_authentication(self, request):
        """
        Perform authentication on the incoming request.

        Note that if you override this and simply 'pass', then authentication
        will instead be performed lazily, the first time either
        `request.user` or `request.auth` is accessed.
        """
        request.user

返回一個Response對象, 也就是rest_framework.request.Request對象ide

Response -> user -> self._authenticatepost

 def _authenticate(self):
        """
        Attempt to authenticate the request using each authentication instance
        in turn.
        """
# self.authenticators 是一個列表, 存放了一個個對象
for authenticator in self.authenticators: try: user_auth_tuple = authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return self._not_authenticated()

APIView -> dispatch -> self.initialize_request -> self.get_authenticators(將對象添加入列表中)ui

    def get_authenticators(self):
        """
        Instantiates and returns the list of authenticators that this view can use.
        """
        return [auth() for auth in self.authentication_classes]

所以能夠在views的類中使用this

class Book(APIView):
  authentication_class = [認證類, ] # 實現局部添加認證類

自定義認證類(能夠在自定義的認證類中添加邏輯)spa

    def _authenticate(self):
        """
        Attempt to authenticate the request using each authentication instance
        in turn.
        """
        for authenticator in self.authenticators:
            try:
# self是一個參數, 因此在自定義驗證類時要傳入request對象 user_auth_tuple
= authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return self._not_authenticated()
class MyAuth():
    def authenticate(self, request):
        pass

class Index(APIView):
    authentication_classes = [MyAuth,]

只要配置了認證類就必定會走認證類, 因此能夠在認證類中寫各類邏輯rest

簡單的登陸認證code

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed
from django.core.exceptions import ObjectDoesNotExist
# rest_framework 自帶的認證類
from rest_framework.authentication import BaseAuthentication
import uuid
class MyAuth(BaseAuthentication):
    def authenticate(self, request):
        # 從地址欄提交token
        token = request.GET.get('token')
        token_obj = models.Token.objects.filter(token=token).first()
        if token_obj:
            # 有值表示登陸了
            return
        else:
            # 沒有值表示沒有登陸
            raise AuthenticationFailed('你沒有登陸')

class Login(APIView):
    def post(self, request):
        response = {'code': 100, 'msg': '登陸成功'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        try:
            # get 有且只有一條纔不報錯,其餘都拋異常
            user = models.User.objects.filter(name=name, pwd=pwd).get()
            # 登陸成功,須要去token表中存數據
            # 生成一個惟一的id
            token = uuid.uuid4()
            # 有則更新,沒有則建立
            models.Token.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        except ObjectDoesNotExist as e:
            response['code'] = 101
            response['msg'] = '用戶名或密碼錯誤'
        except Exception as e:
            response['code'] = 102
            # response['msg'] = '未知錯誤'
            response['msg'] = str(e)
        return Response(response)

 

 

認證類的使用orm

局部使用

class Index(APIView):
    authentication_classes = [MyAuth,]

全局使用

settings文件
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ['app.MyAuths.MyAuth']
}

局部不使用

class Index(APIView):
    authentication_classes = []
相關文章
相關標籤/搜索