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)

  1. class ModelBackend:
  2. """
  3. Authenticates against settings.AUTH_USER_MODEL.
  4. """
  5. ...
  6. def get_user(self, user_id):
  7. try:
  8. user = UserModel._default_manager.get(pk=user_id)
  9. except UserModel.DoesNotExist:
  10. return None
  11. 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配置项

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_AUTHENTICATION_CLASSES': [
  3. 'libs.backend.AuthenticationBackend'
  4. ],
  5. 'DEFAULT_FILTER_BACKENDS': [
  6. 'django_filters.rest_framework.DjangoFilterBackend',
  7. 'rest_framework.filters.SearchFilter',
  8. 'rest_framework.filters.OrderingFilter',
  9. ],
  10. "EXCEPTION_HANDLER": "libs.custom_exception.custom_exception_handler",
  11. # 默认日期时间格式
  12. 'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",
  13. 'DEFAULT_PAGINATION_CLASS': 'libs.pagination.RestPageNumberPagination',
  14. }

在REST_FRAMEWORK中可以配置一个DEFAULT_AUTHENTICATION_CLASSES列表.值通常为一个继承了from rest_framework.authentication import BaseAuthentication的类.重写了authenticate方法.所有继承了drf的APIView的子类中都会得到从这些认证后端中获取到的用户.

一个重要的例外情况

某项目中,因为代码最初的创建者使用的用户类没有继承AbstractUser并且也没有再settings中注册自己的用户模型.导致不继承APIView的类视图和所有函数视图中无法拿到request.user.