Django更改中间件中的request.path(通过url中的令牌进行身份验证)
亲爱的 Stackoverflow 的全知者,
在 Django 1.3 中,我正在制作一个 process_request 中间件,它从 url 获取令牌,让用户登录(如果正确)并从 url 中删除令牌。但是:
我)Django 建议不要在中间件中访问 POST/GET 数据,我不太确定为什么会这样......这同样适用于 request.path 吗? https://docs.djangoproject.com/en/dev/ topic/http/middleware/#process-view
II) 我想从 URL 中删除令牌,因此 /album3/pic42/~53Cr3t70K3n/like/
-> /album3/pic42/like/
。但是更改 request.path 不起作用。找不到页面,而
中间件确实处理正确(通过打印验证)
直接输入
/album3/pic42/like/
确实有效错误(带有令牌)显示
请求 URL: http://www.site.com/album3/pic42/like/
这个问题有解决办法吗,还是我完全从错误的角度来解决这个问题?
提前致谢!
我刚刚意识到要在客户端进行更改,显然我需要重定向(为什么我没有想到这一点......)。然而,能够在没有新请求的情况下仅在服务器端重写它仍然很有用,例如访问个性化图像。
Ps:如果需要更多详细信息,请随意跳过
我正在开发一个向用户发送个性化电子邮件的网站。我希望用户能够单击电子邮件中的链接并通过电子邮件链接中的令牌自动登录。这是对正常登录的补充。 (我知道它不太安全,因为人们可能会转发电子邮件,但它对于我的网站来说已经足够了)。该网址看起来像这样: /album3/pic42/~53Cr3t70K3n/like/ (剥离 http://www.site.com 后,Django 会这样做那)
我正在编写一个中间件来匹配它并在适当的时候让用户登录,一个身份验证后端用于接受令牌作为有效凭证和令牌模型。
中间件process_request函数: def process_request(self, request):
if '/~' in request.path:
result = re.search('(.*)/~(.+?)/(.*)', request.path)
(uidb36, token) = result.group(2).split('-', 2)
user = authenticate(uidb36 = uidb36, token = token)
if user: login(request, user)
return HttpResponseRedirect('%s/%s' % (result.group(1), result.group(3)) + ('?' + '&'.join('='.join(item) for item in request.GET.items()) if request.GET else ''))
return None
现在它可以使用重定向,我也希望能够在内部执行此操作。
Dear omnoscient beings at Stackoverflow,
In Django 1.3 I am making a process_request middleware that gets a token from an url, logs the user in (if it's correct) and removes the token from the url. However:
I) Django recommends against accessing POST/GET data in middleware, I'm not really sure why so... Does the same apply to request.path ? https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-view
II) I want to remove the token from the URL, so /album3/pic42/~53Cr3t70K3n/like/
-> /album3/pic42/like/
. Changing request.path however does not work. The page will not be found, while
The middleware does process correctly (verified by print)
Directly entering
/album3/pic42/like/
does workThe error (with token) shows
Request URL: http://www.site.com/album3/pic42/like/
Is there a fix for this, or am I approaching this from the wrong angle entirely?
Thanks in advance!
I just realized that to change it client side, obviously I need a redirect (why didn't I think of that...). However, it would still be useful to be able to rewrite it just server-side without a new request, for example for accessing a personalized image.
P.s.: more details if needed, feel free to skip
I am working on a site that (will) sends personalized emails to users. I would like users to be able to click links in the email and be logged in automatically, by means of a token in the email link. This is in addition to normal login. (I know it's a less secure because people might forward an e-mail, but it's good enough for my site). The url would look something like this:
/album3/pic42/~53Cr3t70K3n/like/ (with http://www.site.com stripped, Django does that)
I am writing a middleware to match this and log the user in when appropriate, a authentication backend for accepting a token as valid credentials and a token model.
Middleware process_request function:
def process_request(self, request):
if '/~' in request.path:
result = re.search('(.*)/~(.+?)/(.*)', request.path)
(uidb36, token) = result.group(2).split('-', 2)
user = authenticate(uidb36 = uidb36, token = token)
if user: login(request, user)
return HttpResponseRedirect('%s/%s' % (result.group(1), result.group(3)) + ('?' + '&'.join('='.join(item) for item in request.GET.items()) if request.GET else ''))
return None
Right now it works with redirects, I'd like to also be able to do it internally.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您不想搞乱 上传处理程序,我有一个更好的解决方案给你:
在你的 urls.py 中创建一条规则来专门捕获带有令牌的访问
将其放在
urlpatterns
的开头,以确保首先对其进行评估。像这样的事情会做:创建一个视图:
If you don't want to mess up with upload handlers, I have a better solution for you:
Create a rule in your urls.py to specifically catch visits with tokens
Put it at the start of the
urlpatterns
to make sure that it will be evaluated first. Something like this will do:Create a view:
与访问 GET/POST 参数相比,IMO 更改 request.path 更糟糕(如果可以称为糟糕的话),因此只需将令牌作为 GET 参数传递并基于令牌登录,并且不要重定向或进行 request.path 修改
我将令牌视为一个添加到有效 url 的属性,因此中间件承认这一点并使用该令牌执行某些操作,但 url 仍然由正确的视图处理,因此中间件对我来说似乎非常合乎逻辑。
IMO changing request.path is more bad(if it can be called bad) compared to accessing GET/POST parameters, so just pass token as GET parameter and login based on token and do not redirect or do request.path modifications
I see token as a added attribute to a valid url, hence a middleware acknowledges that and does something with that token, but url still is handled by the correct view, so middleware to me seems a very logical fit here.