为什么Django REST Framework提供不同的身份验证机制

时间:2014-06-30 21:34:39

标签: django authentication django-rest-framework restful-authentication

为什么Django REST Framework实现了与内置Django机制不同的身份验证机制?

即,可以配置两个设置类:

    处理Django级别身份验证的
  1. settings.AUTHENTICATION_BACKENDS
  2. settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES']在REST-Framework级别进行身份验证
  3. 我遇到的问题是我有一个中间件层来检查用户是否登录。

    使用通过会话进行身份验证的Web客户端时,这样可以正常工作。但是,从移动设备或运行测试套件(即使用HTTP标头和令牌进行身份验证),中间件会将用户检测为AnonymousUser,但是当我们到达REST Framework层时,HTTP {{1读取头文件,用户登录。

    为什么这些都不会在中间件之前发生?此外,为什么REST框架的身份验证方法不依赖于Django身份验证后端?

2 个答案:

答案 0 :(得分:7)

Django Rest Framework默认情况下不会在中间件中执行身份验证,原因与Django默认情况下不在中间件中执行身份验证的原因相同:中间件适用于所有视图,如果您只想验证对一小部分内容的访问权限,那就太过分了你的意见。此外,能够为不同的API端点提供不同的身份验证方法是一个非常方便的功能。

Rest Framework的身份验证方法不依赖于Django身份验证后端,因为Django的后端针对常见情况进行了优化,并且与用户模型紧密相关。 Rest Framework旨在使其变得容易:

  1. 使用许多不同的身份验证方法。 (您希望基于HMAC的身份验证?已完成!这对于django auth框架来说是不可能的)
  2. 提供API数据,而不需要数据库。 (你有一个redis数据库,你的所有数据都在内存中?以毫秒为单位服务,而不必等待数据库用户模型的往返。)

答案 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框架验证并获取用户。