使用Django Session Framework与令牌而不是Cookie?

时间:2016-01-15 18:13:25

标签: django session authentication oauth django-rest-framework

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

以下是Django提供的原始function changeBtn(elem) { selfile = document.getElementById(elem.id); if ('files' in selfile) { var file = selfile.files[0]; if ('name' in file) { str1 = file.name; } if ('size' in file) { str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)'; } document.getElementById("label_" + elem.id).innerHTML = str1; var FR= new FileReader(); var img = document.createElement("img"); FR.onload = function(e) { img.src = e.target.result; alert(e.target.result); // Returns B64 of the original image }; FR.readAsDataURL(file); var canvas = document.createElement('canvas'); var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var MAX_WIDTH = 800; var MAX_HEIGHT = 600; var width = img.width; var height = img.height; alert(height); // Returns 0 if (width > height) { if (width > MAX_WIDTH) { height *= MAX_WIDTH / width; width = MAX_WIDTH; } } else { if (height > MAX_HEIGHT) { width *= MAX_HEIGHT / height; height = MAX_HEIGHT; } } canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); var dataurl = canvas.toDataURL("image/png"); alert(dataurl); // Returns only "data; " and nothing more } } 。让我们快速浏览一下。

SessionMiddleware.process_request

我们可以清楚地看到它使用设置中定义的def process_request(self, request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) request.session = self.SessionStore(session_key) 属性明确地从cookie中获取会话标识符。因此,我们绝对必须创建自己的SESSION_COOKIE_NAME子类,并定义我们自己的SessionMiddleware行为。

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

process_request

确保将django设置文件中的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替换为自定义会话中间件的路径,并且SessionMiddleware应该开始根据输入令牌为您提供数据。

注意:您可能还需要修改requests.session行为,因为您可能不需要发回process_response标题。