Stackoverflow的亲爱的无所不在的生物,
在Django 1.3中我创建了一个process_request中间件,它从一个url获取一个令牌,记录用户(如果正确)并从url中删除令牌。但是:
I)Django建议不要访问中间件中的POST / GET数据,我不确定为什么这样......请问同样适用于request.path? https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-view
II)我想从网址中删除令牌,因此/album3/pic42/~53Cr3t70K3n/like/
- > /album3/pic42/like/
。但是更改request.path不起作用。
中间件确实处理正确(通过打印验证)
直接输入/album3/pic42/like/
确实有效
错误(带令牌)显示Request URL: http://www.site.com/album3/pic42/like/
有没有解决这个问题,还是我完全从错误的角度接近这个?
提前致谢!
我刚刚意识到要改变它的客户端,显然我需要一个重定向(为什么我没想到......)。但是,如果能够在没有新请求的情况下在服务器端重写它,仍然有用,例如访问个性化图像。
P.s。:如果需要更多细节,随意跳过
我正在开发一个(将)向用户发送个性化电子邮件的网站。我希望用户能够点击电子邮件中的链接,并通过电子邮件链接中的令牌自动登录。这是正常登录的补充。 (我知道它不太安全,因为人们可能转发电子邮件,但这对我的网站来说已经足够了)。网址看起来像这样: / 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
现在它适用于重定向,我也希望能够在内部完成。
答案 0 :(得分:2)
如果您不想陷入upload handlers,我会为您提供更好的解决方案:
在您的urls.py中创建规则以专门捕获带有令牌的访问
将其放在urlpatterns
的开头,以确保首先评估它。这样的事情会做:
(r'/~', 'my_app_name.my_redirect_view'),
创建视图:
def my_redirect_view(request):
#Compiled regular expressions work much faster
beloved_tokens = re.compile(r'(.*)/~(.+?)/(.*)')
result = beloved_tokens.search(request.path)
try:
(uidb36, token) = result.group(2).split('-', 2)
path_end = result.group(3)
# We use "try" to be sure that no one had
# messed with our beloved tokens:
except AttributeError:
raise Http404
else:
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 ''))
else:
raise Http404
答案 1 :(得分:1)
与访问GET / POST参数相比,IMO更改request.path更糟糕(如果它可以被称为坏),所以只需将令牌作为GET参数传递并基于令牌登录,不要重定向或执行request.path修改< / p>
我将令牌视为有效网址的附加属性,因此中间件会确认并使用该令牌执行某些操作,但网址仍由正确的视图处理,因此对我来说中间件似乎非常符合逻辑。