认证组件
在执行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'
),.....}
View Code
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
View Code
首先执行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函数