认证类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 = []