Loading

38.认证系统

认证
  • 身份验证是将传入的请求与一组鉴别凭据关联的机制,然后使用权限和限流策略来确定是否允许请求进入
  • 再权限和限流检查发生之前,以及在执行其他代码之前,实在在视图的最开始处运行身份验证
  • 也就是说认证过程优先级最高,最先被执行
  • request.user属性通常设置为contrib.auth包的user类的实例,这是Django原生的做法
  • request.auth属性用于任何其他附加的身份验证信息,例如表示请求中携带的身份验证令牌
  • 上面两个位置request中的属性是认真和权限机制的核心数据
 
 
认证的机制
  • 允许使用的认证模式一般以一个类的列表的配置形式存在
  • drf会尝试使用列表中的每个类进行认证,并使用第一个成功通过验证类的返回值设置request.user和request.auth
  • 如果所有的认证类尝试了一遍都没有通过验证
  • request.user将被设置为django.contrib.auth.models.AnonymousUser的实例,也就是匿名用户
  • request.auth将被设置为None
  • drf的认证机制依赖Django的auth框架
  • 未认证用户请求过程中,request.user和request.auth的值可以通过UNAUTHENTICATED_USER 和 UNAUTHENTICATED_TOKEN两个配置修改
 
 
认证功能核心源代码
 位于request.py模块中


# 每个认证类的实例验证请求
def _authenticate(self):
    # 循环指定的所有认证类型
    for authenticator in self.authenticators:
        try:
            # 执行认证类的authenticate方法,返回值是一个(user,auth)元组
            user_auth_tuple = authenticator.authenticate(self)
        except exceptions.APIException: #如果认证失败或者错误
            self._not_authenticated() #执行认证失败后的方法
            raise # 向上抛出异常
        # 如果user_auth_tuple不为none 认证通过
        if user_auth_tuple is not None: 
            #将通过认证的认证类保存
            self._authenticator = authenticator
            # 将返回值赋值给request对象的user和auth
            self.user, self.auth = user_auth_tuple
            return #上面已经将需要的值保存了,所以什么也不返回
    # 走完循环都没有认真成功,执行认证失败后的方法
    self._not_authenticated()
    
#认证失败后的方法
def _not_authenticated(self):
    # request中认证器为None,也就是没有认证通过
    self._authenticator = None
    # 如果UNAUTHENTICATED_USER有设置值
    if api_settings.UNAUTHENTICATED_USER:
        # user = 设置的值,默认是AnonymousUser
        self.user = api_settings.UNAUTHENTICATED_USER()
    else:
        # 没有设置的话,user=None
        self.user = None
     # 如果UNAUTHENTICATED_TOKEN有设置值
    if api_settings.UNAUTHENTICATED_TOKEN:
        #auth = UNAUTHENTICATED_TOKEN的值
        self.auth = api_settings.UNAUTHENTICATED_TOKEN()
    else:
        # 没有设置的话 auth =None
        self.auth = None
 
配置认证方案
全局认证:通过DEFAULT_AUTHENTICATION_CLASSES配置项,可以进行全局性认证方案配置
#全局默认的认证配置
# 全局配置完之后 所有的视图都会进行认证
REST_FRAMEWORK = {
    
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.BasicAuthentication', #基础
    'rest_framework.authentication.SessionAuthentication', #会话
     )
}
视图级别的认证配置
# 基于视图类APIView的认证
# 导入认证模块
from rest_framework.authentication import TokenAuthentication,BaseAuthentication

# 继承APIView类 或者其他继承了APIView的视图类
class AuthViewSet(APIView):

    # 指定认证类
    authentication_classes = [TokenAuthentication, BaseAuthentication]
 
#使用@api_view装饰器指定视图级别认证

@api_view(['POST'])
@authentication_classes((TokenAuthentication, BaseAuthentication,))#指定认证
@permission_classes((IsAuthenticated,))#指定权限
def getInfo(request):
    ...
 
# 如果想要某个视图不使用认证功能
# 设置认证类为一个空列表,会覆盖全局配置,即为空不进行认证
authentication_classes = []
未认证和拒绝响应
#当未经身份验证的请求被拒绝时有两种响应
HTTP 401 Unauthorized : 响应会包含一个WWW-AUthenticate头部属性,用于指引用户如何认证
HTTP 403 Permission Denied :响应不会包含WWW-AUthenticate
#只能使用一个方案来确定响应类型,根据视图设置的第一个身份认证类确定响应类型
#如果请求成功但仍被拒绝执行,无论身份验证怎么样,都会返回403的响应
 

posted @ 2022-10-09 11:00  木子七  阅读(64)  评论(0编辑  收藏  举报