認證類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 = []