如何向 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 请求对象添加属性的主要内容,如果未能解决你的问题,请参考以下文章