rest-framework认证组件
认证组件
在执行APIView时的操作流程:
1.执行dispatch
在执行APIView中的dispatch方法时,在执行handler函数之前,会执行
self.initial(request, *args, **kwargs),此函数的功能有:
1.版本处理
2.用户认证
3.权限
4.访问频率限制
2.执行self.initial(request, *args, **kwargs)
def initial(self, request, *args, **kwargs): #设置响应器 neg = self.perform_content_negotiation(request) #1.处理版本信息 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme #2.认证 self.perform_authentication(request) #3.权限 self.check_permissions(request) #4.请求用户进行访问频率的限制 self.check_throttles(request)
3.执行self.perform_authentication(request)
def perform_authentication(self, request):
request.user
self.perform_authentication(request)的值就是request.user的值
1.执行request.user,需要知道request是什么,request是封装后的request,返回dispatch中找到这个request
def dispatch(self, request, *args, **kwargs):
request = self.initialize_request(request, *args, **kwargs)
2.找到initialize_request函数,initialize_request返回Request的实例对象
def initialize_request(self, request, *args, **kwargs): parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context )
3.那么request就是Request的对象,执行request.user就是调用Request类中的user方法
request.user=Response().user
4.找到Request类,找到uesr方法
class Request(object): def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None): self._request = request self.parsers = parsers or () self.authenticators = authenticators or () @property def user(self): if not hasattr(self, '_user'): with wrap_attributeerrors(): self._authenticate() return self._user
在uesr方法中,执行_authenticate函数,此时的self是request对象,不是当前类
因此在Request类找到_authenticate方法。
request.user=self._authenticate()
1.执行_authenticate方法:
def _authenticate(self): 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.authenticators,查找authenticators函数
class Request(object): def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None): self.authenticators = authenticators or ()
2.self.authenticators = authenticators or ()
self.authenticators就是Request实例化时的参数authenticators Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context ) 找到self.get_authenticators(),此时的self是当前类对象
找到self.get_authenticators(),此时的self是当前类对象
3.authenticators=self.get_authenticators(),
def get_authenticators(self): return [auth() for auth in self.authentication_classes]
4.self.get_authenticators()=[],找到self.authentication_classes的值
从当前类中查找authentication_classes属性,如果在当前类中我们定义了authentication_classes
就用我们定义的,如果当前类未定义就去父类中查找。因此我们在类中定义这个变量时值要设为可变类型
1.当前类中定义:
class AuthorModelView(ModelViewSet):
authentication_classes = [AuthUser]
循环这个列表,进行实例化,此时authenticators的值为[AuthUser(),]
2.当前类中未定义authentication_classes时,去父类中查找,在APIView中找到authentication_classes
class APIView(View): authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
1.去api_settings中找DEFAULT_AUTHENTICATION_CLASSES属性:
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
api_settings是 APISettings的对象,去类中调用DEFAULT_AUTHENTICATION_CLASSES属性
2.class APISettings(object):
class APISettings(object): def __init__(self, user_settings=None, defaults=None, import_strings=None): if user_settings: self._user_settings = self.__check_user_settings(user_settings) self.defaults = defaults or DEFAULTS def __getattr__(self, attr): if attr not in self.defaults: raise AttributeError("Invalid API setting: '%s'" % attr) try: val = self.user_settings[attr] except KeyError: val = self.defaults[attr]
在 APISettings中并没有DEFAULT_AUTHENTICATION_CLASSES属性,因此执行__getattr__方法
attr的值为DEFAULT_AUTHENTICATION_CLASSES
3.执行__getattr__
找到self.defaults的值,在APISettings实例化时 defaults的值为DEFAULTS,在init中self.defaults=DEFAULTS
DEFAULTS = { # Base API policies 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ),.....}
DEFAULT_AUTHENTICATION_CLASSES在self.defaults中,执行try
val = self.user_settings[attr],找到self.user_settings
@property def user_settings(self): if not hasattr(self, '_user_settings'): self._user_settings = getattr(settings, 'REST_FRAMEWORK', {}) return self._user_settings
self.user_settings就是getattr的结果
getattr(settings, 'REST_FRAMEWORK', {})在settings文件中反射REST_FRAMEWORK
如果setting配置了self.user_settings的值就为配置的结果,如果未配置,就未{}
情况1:在settings中配置了REST_FRAMEWORK
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":( "app01.service.auth.AuthUser", ),}
此时self.user_settings={"DEFAULT_AUTHENTICATION_CLASSES":("app01.service.auth.AuthUser",),}
情况2:未配置self.user_settings={}
try: val = self.user_settings[attr] except KeyError: val = self.defaults[attr] 在self.user_settings中找到DEFAULT_AUTHENTICATION_CLASSES的值
1.如果能找到val就为这个值,在配置的情况下,val等于我们自定义的值("app01.service.auth.AuthUser",)
2.未找到,就去self.defaults中找,并取值,此时值为默认设置的
val=(
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
)
在当前类中未定义认证组件时,去APIView中调用对应的属性,在去settings中找REST_FRAMEWORK变量,如果这个变量存在,就取到
以这个属性为key的键值对的value作为authentication_classes的值
settings未自定义REST_FRAMEWORK变量,就使用默认设置,即DEFAULTS定义的value作为authentication_classes的值
在当前类中定义authentication_classes的话:将类进行实例化处理
1.self.get_authenticators()=[AuthUser()]
2.在当前类未定义,在settings中设置的话,就将settings对应的values进行实例化处理:self.get_authenticators()=[AuthUser()]
3.settings中未设置,实例化DEFAULTS中对应的values值:self.get_authenticators()=[SessionAuthentication(),BasicAuthentication()]
5.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
首先执行try,执行实例对象中的authenticate方法,因此在自当以类中,我们在设置时,函数名必须是这个,返回值为user_auth_tuple
如果执行有误,就抛异常
如果user_auth_tuple的值不为空,就将值分别赋给user,auth,因此我们在设计时,要返回一个元祖,返回值可用request来调用
6.self.perform_authentication(request)
self._authenticate()的值就是authenticate函数执行的结果,从而request.user的值就是authenticate函数执行的结果
因此self.perform_authentication(request)执行的就是authenticate函数
整体流程
流程1:
流程2:
流程3