使用带有令牌而不是 Cookie 的 Django 会话框架?

Posted

技术标签:

【中文标题】使用带有令牌而不是 Cookie 的 Django 会话框架?【英文标题】:Using Django Session Framework with a Token instead of a Cookie? 【发布时间】:2016-04-21 09:52:02 【问题描述】:

我有一个带有受保护端点的 DRF API,它根据用户有权访问的内容返回过滤数据。

我有一个单独的 Django OAuth2 提供程序,其中包含用户模型和确定用户有权访问什么所需的值。

用户应该能够通过 DRF API 上的登录端点进行身份验证。 API 反过来代表用户从 Oauth2 提供程序获取令牌,并进行几次调用以获取允许用户访问的资源列表。

理想情况下,DRF API 会生成一个令牌并将其返回给用户。每当用户使用令牌发出后续请求(登录后)时,API 将能够通过调用 Oauth 提供程序返回的值过滤结果。

问题是如何存储这些信息。这感觉类似于在匿名用户会话中存储数据,但使用请求标头而不是 cookie。我考虑过推出 django.contrib.sessions.middleware.SessionMiddleware 的自定义版本,但我更喜欢使用已建立的方法而不是编写自定义代码,因为这似乎不是一个独特的问题。

重申一下:是否可以创建匿名用户会话,在其中存储信息,然后通过请求标头而不是 cookie 检索会话?

【问题讨论】:

【参考方案1】:

这是 Django 提供的原始SessionMiddleware.process_request。让我们快速浏览一下。

def process_request(self, request):
    session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
    request.session = self.SessionStore(session_key)

我们可以清楚地看到,它使用设置中定义的SESSION_COOKIE_NAME 属性从cookie 中显式获取会话标识符。因此,我们绝对必须创建自己的 SessionMiddleware 子类并定义自己的 process_request 行为。

无论传入的令牌是否经过身份验证,我们都需要从标头中检索令牌值,并使用它来启动我们的会话引擎。以下是它的外观:

from django.contrib.sessions.middleware import SessionMiddleware
from django.conf import settings

class CustomSessionMiddleware(SessionMiddleware):
    def process_request(self, request):
         session_key = request.META.get("HTTP_%s" % settings.SESSION_KEY_NAME, None)
         request.session = self.SessionStore(session_key)

确保将 django 设置文件中的 SESSION_KEY_NAME 属性设置为将发送此令牌的标头键的名称。然后,将 django 的原始 SessionMiddleware 替换为您的自定义会话中间件的路径,您的 requests.session 应该开始根据输入令牌为您提供数据。

注意:您可能还需要修改 process_response 行为,因为您可能不需要发回 Set-Cookie 标头。

【讨论】:

以上是关于使用带有令牌而不是 Cookie 的 Django 会话框架?的主要内容,如果未能解决你的问题,请参考以下文章

通过 cookie 标头发送令牌身份验证信息是不是安全?

使用 Http 和 Secure 将 Jwt 令牌存储在 Cookie 中,而不是 Javascript 中的 LocalStorage

带有 API 令牌的 Laravel 会话 cookie

在启用 SSL 的站点上使用 JWT 而不是 Cookie

使用 CSRF_COOKIE_HTTPONLY 将 Django CSRF 令牌传递给 Angular

如何通过令牌而不是cookie中的jsession访问spring oauth2客户端后端api?