如何向 Django 请求对象添加属性

Posted

技术标签:

【中文标题】如何向 Django 请求对象添加属性【英文标题】:How to add an attribute to Django request object 【发布时间】:2021-06-19 23:26:01 【问题描述】:

我尝试使用我自己的中间件将business 属性添加到请求对象,它与rest_framework.authentication.SessionAuthentication 很好地配合使用,我可以在我的视图中使用request.business。但是当我尝试使用 JWT 方法 (rest_framework_simplejwt.authentication.JWTAuthentication) 进行身份验证时,当我的中间件代码运行时 request.user 设置为 AnonymouseUser 所以无法获取与 user 关联的业务?为什么会这样?

# middleware.py

class MyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.business = None

        if request.user.is_authenticated and hasattr(request.user, 'business'):
            request.business = request.user.business

        response = self.get_response(request)

        return response

中间件:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'my_app.middleware.MyMiddleware',
]

rest_framework 设置:

REST_FRAMEWORK = 
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],

【问题讨论】:

你能展示你的中间件列表来看看它们是如何排序的吗? 是的,已更新。 @Charnel 这能回答你的问题吗? Django and Middleware which uses request.user is always Anonymous 【参考方案1】:

不幸的是,DEFAULT_AUTHENTICATION_CLASSES 不是在中间件进程中处理的,而是在视图本身中处理的。使用会话时为您提供正确用户的是 Django 的AuthenticationMiddleware,而 REST 框架仅在启用会话身份验证时使用此值。

要解决这个问题,您可以执行以下操作之一:

request.business 添加到视图中(例如,添加一些您的所有视图都将从中继承的类) 将 JWT 身份验证移至 Django 中间件(这会在用户登录时默认执行 DRF 强制 CSRF 检查的副作用)

【讨论】:

以上是关于如何向 Django 请求对象添加属性的主要内容,如果未能解决你的问题,请参考以下文章

向 Express 请求对象添加属性

Django:向视图中的请求添加可选参数

django 根据请求向所有视图添加上下文

尝试向 API 发送 POST 请求时出现属性错误 - Django

如何检查唯一的 bulk_create

如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?