def authenticate(self, request):
"""
Authenticate the request and return a two-tuple of (user, token).
“”"
raise NotImplementedError(“.authenticate() must be overridden.”)
def authenticate\_header(self, request):
"""
Return a string to be used as the value of the WWW-Authenticate
header in a 401 Unauthenticated
response, or None
if the
authentication scheme should return 403 Permission Denied
responses.
“”"
pass
#基于用户名和密码的认证
class BasicAuthentication(BaseAuthentication):
#基于session的认证
class SessionAuthentication(BaseAuthentication):
#基于token的认证
class TokenAuthentication(BaseAuthentication): —
#远程用户认证
class RemoteUserAuthentication(BaseAuthentication):
“”"
REMOTE_USER authentication.
To use this, set up your web server to perform authentication, which will
set the REMOTE_USER environment variable. You will need to have
'django.contrib.auth.backends.RemoteUserBackend in your
AUTHENTICATION_BACKENDS setting
“”"
#### 认证流程
**authentication\_classes**
**请求到dispatch方式**
def dispatch(self, request, *args, **kwargs):
“”"
.dispatch()
is pretty much the same as Django’s regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
“”"
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
**调用self.initial()**
def initial(self, request, *args, **kwargs):
self.perform_authentication(request)
**调用 perform\_authentication() 返回request.user**
def perform_authentication(self, request):
request.user
\*\*在dispatch中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
)
**Request 有方法注解 user 调用\_authenticate 循环认证对象 执行方法**
@property
def user(self):
if not hasattr(self, ‘_user’):
with wrap_attributeerrors():
self._authenticate()
return self._user
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._not_authenticated()
#### 使用方法
* 全局使用
**自定义的认证类可以通过全局设置 放在setting文件中 源码中会读取setting中的**
REST_FRAMEWORK={
‘DEFAULT_AUTHENTICATION_CLASSES’=(‘自定义的认证类’),
‘UNAUTHENTICATED_USER’:None,
‘UNAUTHENTICATED_TOKEN’:None
}
* 局部使用(视图级别的认证)
**内置的认证类 rest\_framework.authentication BasicAuthentication**
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class MyAuth(BaseAuthentication):
def authenticate(self, request):
if request.method in [“POST”, “PUT”, “DELETE”]:
request_token = request.data.get(“token”, None)
if not request_token:
raise AuthenticationFailed(‘缺少token’)
token_obj = models.Token.objects.filter(token_code=request_token).first()
if not token_obj:
raise AuthenticationFailed(‘无效的token’)
return token_obj.user.username, None
else:
return None, None
继承 BasicAuthentication 创建自定义的认证类 实现 authenticate方法
添加到视图类的 authentication\_classes
class CommentViewSet(ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth, ]