drf总流程链接
https://www.cnblogs.com/daviddd/p/11918405.html
drf之auth认证
'''
承上rest_framework总流程的5.2认证
认证:
1. 执行dispatch方法,中的initialize_request
封装新的request,然后执行get_authenticators,实例化认证类对象列表,并封装到request中
2. 执行initial中的perform_authrentication 方法,执行request.user 中的_authenticate
方法,循环认证类对象列表,并执行authenticate方法,返回none,或者一个元组,或者抛出异常
'''
class APIView(View):
# 3.22authentication_classes 配置,全局配置在settings文件中或自定义在需要的类中
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
settings = api_settings
schema = DefaultSchema()
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
# 承接总流程的3.2过程
authenticators=self.get_authenticators(),
)
# 3.21实例化认证函数并存放到一个列表中
def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes]
# 封装请求头后执行initial函数,版本,认证。。。
def initial(self, request, *args, **kwargs):
# 5.2认证
self.perform_authentication(request)
# 5.21当后端执行request.user时,调用request的user()函数
def perform_authentication(self, request):
"""
Perform authentication on the incoming request.
Note that if you override this and simply 'pass', then authentication
will instead be performed lazily, the first time either
`request.user` or `request.auth` is accessed.
"""
request.user
# 5.22封装request.user,request.auth
@property
def user(self):
"""
Returns the user associated with the current request, as authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
# 5.23
with wrap_attributeerrors():
# 5.24
self._authenticate()
return self._user
def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
for authenticator in self.authenticators:
try:
# 5.25,调用认证类中的authenticate函数,自己定义则调用自己的
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise
# 5.27得到authenticate的返回值user_auth_tuple,封装user,auth
if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
return
# 5.28 user,auth 分类
self._not_authenticated()
# 5.26执行认证类中的authenticate函数,自己定义则执行自己的,返回返回值
def authenticate(self, request):
"""
Returns a `User` if a correct username and password have been supplied
using HTTP Basic authentication. Otherwise returns `None`.
"""
# 5.261封装auth
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != b'basic':
return None
if len(auth) == 1:
msg = _('Invalid basic header. No credentials provided.')
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = _('Invalid basic header. Credentials string should not contain spaces.')
raise exceptions.AuthenticationFailed(msg)
try:
auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':')
except (TypeError, UnicodeDecodeError, binascii.Error):
msg = _('Invalid basic header. Credentials not correctly base64 encoded.')
raise exceptions.AuthenticationFailed(msg)
userid, password = auth_parts[0], auth_parts[2]
# 5.262封装user
return self.authenticate_credentials(userid, password, request)
# 5.29 执行_not_authenticated函数,UNAUTHENTICATED_USER,UNAUTHENTICATED_TOKEN可以自定义
def _not_authenticated(self):
"""
Set authenticator, user & authtoken representing an unauthenticated request.
设置表示未经身份验证的请求的身份验证器、用户和身份验证器。默认值为"无"、"匿名用户"和"无
Defaults are None, AnonymousUser & None.
# Authentication
'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
'UNAUTHENTICATED_TOKEN': None,
"""
self._authenticator = None
if api_settings.UNAUTHENTICATED_USER:
self.user = api_settings.UNAUTHENTICATED_USER()
else:
self.user = None
if api_settings.UNAUTHENTICATED_TOKEN:
self.auth = api_settings.UNAUTHENTICATED_TOKEN()
else:
self.auth = None