SessionMiddleware和AuthenticationMiddleware
后者必须放在前者之后.前者为会话做hash和kv存储后.后者再将用户与会话关联起来
如果未使用django默认的session认证机制可以无视这两个中间件
AUTHENTICATION_BACKENDS
这个配置项是django默认的认证后端列表.AuthenticationMiddleware
会调用get_user
会调用auth.get_user
会调用user_id = _get_user_session_key(request)
和backend.get_user(user_id)
class ModelBackend:
"""
Authenticates against settings.AUTH_USER_MODEL.
"""
...
def get_user(self, user_id):
try:
user = UserModel._default_manager.get(pk=user_id)
except UserModel.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None # user_can_authenticate判断user的is_active属性.
默认的backend就是这个ModelBackend.可以看到如果用户类没有使用django默认的机制注册的话可能会因为没有seission_id和用户的map而导致此时request.user为None.
DEFAULT_AUTHENTICATION_CLASSES
一个常见的drf配置项
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'libs.backend.AuthenticationBackend'
],
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter',
],
"EXCEPTION_HANDLER": "libs.custom_exception.custom_exception_handler",
# 默认日期时间格式
'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",
'DEFAULT_PAGINATION_CLASS': 'libs.pagination.RestPageNumberPagination',
}
在REST_FRAMEWORK中可以配置一个DEFAULT_AUTHENTICATION_CLASSES列表.值通常为一个继承了from rest_framework.authentication import BaseAuthentication
的类.重写了authenticate
方法.所有继承了drf的APIView
的子类中都会得到从这些认证后端中获取到的用户.
一个重要的例外情况
某项目中,因为代码最初的创建者使用的用户类没有继承AbstractUser并且也没有再settings中注册自己的用户模型.导致不继承APIView
的类视图和所有函数视图中无法拿到request.user.