为什么Django REST Framework实现了与内置Django机制不同的身份验证机制?
即,可以配置两个设置类:
settings.AUTHENTICATION_BACKENDS
和settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES']
在REST-Framework级别进行身份验证我遇到的问题是我有一个中间件层来检查用户是否登录。
使用通过会话进行身份验证的Web客户端时,这样可以正常工作。但是,从移动设备或运行测试套件(即使用HTTP标头和令牌进行身份验证),中间件会将用户检测为AnonymousUser
,但是当我们到达REST Framework层时,HTTP {{1读取头文件,用户登录。
为什么这些都不会在中间件之前发生?此外,为什么REST框架的身份验证方法不依赖于Django身份验证后端?
答案 0 :(得分:7)
Django Rest Framework默认情况下不会在中间件中执行身份验证,原因与Django默认情况下不在中间件中执行身份验证的原因相同:中间件适用于所有视图,如果您只想验证对一小部分内容的访问权限,那就太过分了你的意见。此外,能够为不同的API端点提供不同的身份验证方法是一个非常方便的功能。
Rest Framework的身份验证方法不依赖于Django身份验证后端,因为Django的后端针对常见情况进行了优化,并且与用户模型紧密相关。 Rest Framework旨在使其变得容易:
答案 1 :(得分:0)
托马斯的答案很好地解释了原因。我的答案涉及更多您可以采取的措施。我还有一个确定当前用户的中间件类。我需要这样做是因为我们有一些自动流程(cron),并且我想将这些属性归给超级用户,并且我有一些模型函数无法访问请求对象,但需要知道当前用户是谁。功能。因此,当您通过REST框架添加API时,这会引起一些问题。这是我的解决方案(您需要针对您的用例进行调整):
from threading import local
_user = local() # thread-safe storage for current user used by middleware below
class CurrentUserMiddleware(object):
""" Defines Middleware for storing the currently active user """
def process_request(self, request):
if not request:
# Clear the current user if also clearing the request.
_user.value = 1 # One represents automatic actions done by super admin
else:
_user.value = request.user
if not _user.value or not _user.value.is_authenticated:
try:
authenticator = TokenAuthentication()
auth = authenticator.authenticate(request)
if auth:
_user.value = auth[0]
except Exception as e:
pass
def process_response(self, request, response):
_user.value = None
return response
验证器位用于查看请求是否已由REST框架验证并获取用户。