一:源码分析
(1)认证组件
(1)视图
PIView的dispath(self, request, *args, **kwargs)
知识兔(2)任务分发
ispath方法内 self.initial(request, *args, **kwargs) 进入三大认证
知识兔(3)认证组件
self.perform_authentication(request)
知识兔(4)认证功能介绍
(1)其主要用来对用户进行认证
(2)检验用户 ----> 普通游客 | 合法用户 | 非法用户
(3)游客:代表认证通过 直接进入下一步(权限校验)
(2)合法用户:携带验证信息进行验证 验证通过将用户存储进入request.user中 再次进行下一步校验
(3)非法用户:携带验证信息进行验证 验证失败直接抛出异常 返回403权限问题
(2)源码分析
(1)第一步APIView/dispatch/initial
def initial(self, request, *args, **kwargs):# Ensure that the incoming request is permitted
self.perform_authentication(request) # 认证功能
self.check_permissions(request) # 访问权限功能
self.check_throttles(request) # 频率功能
知识兔(2)第二步进入认证功能
def perform_authentication(self, request):
request.user # 得到一个方法属性 get方法
PS: 如果是复制属性 应该是request.user = XXX
知识兔(3)第三步进入request/user
@property
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate() # 没有用户认证处用户
return self._user # 如果有直接返回用户
知识兔(4)第四步_authenticate
def _authenticate(self):
# self.authenticators:一堆认证类产生序列化认证对象的集合体(列表)
for authenticator in self.authenticators: # 循环遍历集合体拿到一个个认证对象
try:
'''
authenticator.authenticate:认证对象调用认证功能
user_auth_tuple:拿到登录的用户与用户信息的返回值
调用改方法传入两个参数 self,request
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
# 如果有返回值 将登录用户 与 验证信息 保存在 request.user ,request.author
self.user, self.auth = user_auth_tuple
return
# 如果返回值为空 代表认证通过 但是没有登录用户 与验证信息 表示当前用户为游客用户
self._not_authenticated()
知识兔(5)自定义认证组件
(1)全局settings文件配置
{
# 全局配置异常模块
'EXCEPTION_HANDLER': 'utils.exception.exception_handler',
# 认证类配置
'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
'api.authentications.MyAuthentication', # 自定义认证组件
],
# 权限类配置
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
}
知识兔(2)自定义文件配置api/Authentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication
from . import models
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
'''
前台在请求头携带认证信息,
且默认规范用 Authorization 字段携带认证信息,
后台固定在请求对象的META字段中 HTTP_AUTHORIZATION 获取
'''
auth = request.META.get('HTTP_AUTHORIZATION',None) # 可以不携带认证信息
if auth is None: # 如果为空则表明游客
return None # 没有登录用户 与 返回信息
auth_list = auth.split() # 设置认证小规则(两段式)
# 判断用户是否合法
if not (len(auth_list) == 2 and auth_list[0].lower() == 'auth'):
raise AuthenticationFailed('认证信息有误 非法用户') # 非法的请求 直接抛出异常
# 解析合法的用户
if not auth_list[1] == 'qwe.asd.zxc': # 假设通过解析'qwe.asd.zxc' 可以解析处合法用户
raise AuthenticationFailed('用户校验失败 非法用户')
user_obj = models.User.objects.filter(username='admin').first()
if not user_obj:
raise AuthenticationFailed('用户数据有误 非法用户')
return (user_obj,None) # 合法将用户返回 验证信息不返回
知识兔(3)视图层
from rest_framework.views import APIView
from rest_framework.response import Response
class TestAPIView(APIView):
def get(self,request,*args,**kwargs):
'''
测试一:前段不输入校验信息 获取用户属于匿名用户
测试二:前段加入验证信息 获取用户属于解析用户 admin
'''
print(request.user)
return Response(
{
'status':0,
'msg':'测试成功'
}
)
知识兔