在开发后端API的时候,不同的功能可能有不同的限制,如
这个时候我们就可以使用DRF提供的认证组件,下面通过一个例子介绍
我们希望用户在登录之后,才能访问订单页面
模型类
from django.db import models class UserInfo(models.Model): username = models.CharField(verbose_name="用户名", max_length=32) password = models.CharField(verbose_name="密码", max_length=64) token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)
用户登录类
""" 根据前端传递过来的用户名和密码,生成对应的token,返回给前端 """ class AuthView(APIView): """ 用户登录验证 """ def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') user_object = UserInfo.objects.filter(username=username, password=password).first() if not user_object: return Response( { 'code': 1000, 'data': '用户名或者密码错误' } ) token = str(uuid.uuid4()) user_object.token = token user_object.save() return Response({ 'code': 0, 'data': {'token': token, 'name': username} })
认证类
from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class MyAuthentication(BaseAuthentication): def authenticate(self, request): token = request.query_params.get('token') if not token: raise AuthenticationFailed({ 'code': 1000, 'data': '验证失败', }) user_object = UserInfo.objects.filter(token=token).first() if not user_object: raise AuthenticationFailed({ 'code': 1000, 'data': '验证失败', }) return user_object, token def authenticate_header(self, request): return 'Bearer realm="API"'
-
-
authenticate_header函数将返回值设置给响应头
WWW-Authenticate
-
对于验证失败,抛出
AuthenticationFailed
异常 -
验证成功,则返回一个元组,第一个元素为当前登录用户对象,第二个为验证token,封装在request中
-
request.user
-
Request.auth
-
-
订单视图类
class OrderView(APIView): authentication_classes = [MyAuthentication, ] def get(self, request, *args, **kwargs): print(request.user) print(request.auth) return Response({ 'code': 0, 'data': '订单数据' })
在视图类中设置类变量 authentication_classes的值为 认证类 MyAuthentication,表示此视图在执行内部功能之前需要先经过 认证。
认证类是可以使用多个的,从上面中列表就可以知道,一般情况下一个认证类就够了。但有时候我们需要支持多种验证方式
在请求中使用token
进行cookie验证
...
关于返回None
-
-
当出现多个认证类时,drf内部会按照列表的顺序,逐一执行认证类的
authenticate
方法,如果 返回元组 或 抛出异常 则会终止后续认证类的执行;如果返回None,则意味着继续执行后续的认证类。 -
如果所有的认证类
authenticate
全局配置
REST_FRAMEWORK = { "UNAUTHENTICATED_USER": lambda: None, "UNAUTHENTICATED_TOKEN": lambda: None, "DEFAULT_AUTHENTICATION_CLASSES":["xxxx.xxxx.xx.类名","xxxx.xxxx.xx.类名",] }
底层源码实现
-
抛出异常,则终止验证,返回可前端错误数据
-
返回None,跳过该验证类,执行下一个验证类的authenticate
-