drf之auth认证

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

自定义authenticate方法

from rest_framework.authentication import BaseAuthentication
from api import models
class TokenAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get("token")
print(f'token:{token}')
if not token:
return (None, None)
user_obj = models.UserInfo.objects.filter(token=token).first()
if user_obj:
return (user_obj, token)
return (None, None)

配置文件

REST_FRAMEWORK = {"DEFAULT_AUTHENTICATION_CLASSES": ['myviews.extensions.auth.TokenAuthentication'],}

posted @ 2019-11-23 16:25  阿浪阿浪  阅读(597)  评论(0)    收藏  举报