【问题标题】:Django, csrf_token does not appear on form after redirectionDjango,csrf_token 重定向后没有出现在表单上
【发布时间】:2014-03-03 01:03:03
【问题描述】:

我正在使用此中间件将所有页面重定向到登录页面:(AuthRequiredMiddleware 类的一部分。

def process_request(self, request):
    assert hasattr(request, 'user') 
    if not request.user.is_authenticated():
        path = request.path_info.lstrip('/')
        if path not in ['ipn/', 'pp_cancel/', 'pp_success/', 'sitemap/', 'welcome/']:
            lang = request.GET.get('lang', 'en')
            ru = request.GET.get('ru', '')
            return render_to_response('landing_en.html', RequestContext(request, {'ru': ru}))

这是我的settings.py

MIDDLEWARE_CLASSES = (                                                                                                                                                                                   
     'django.middleware.cache.UpdateCacheMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'main.common.SessionBasedLocaleMiddleware.SessionBasedLocaleMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.cache.FetchFromCacheMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'main.common.tz_middleware.TimezoneMiddleware',
     'main.common.sslMiddleware.SSLRedirect',
     'main.common.RedirectAllMiddleware.AuthRequiredMiddleware',
)

如果 url 是(例如)/welcome/ 并且没有执行重定向,{% csrf_token %} 工作并显示在表单中。如果用户被重定向,则表单中不会显示 csrf_token。

我做错了什么?

【问题讨论】:

  • 我相信这是 csrf 提供的保护的一部分(主要问题是跨站点伪造,有人冒充用户但来自不同的 url)。我不确定如何将其转化为解决方案,但可以尝试使用 render 而不是 render_to_response。它确保所有上下文处理器都能正常工作,所以也许这会有所帮助
  • 这不是重定向! HttpResponseRedirect 是一个重定向。
  • RequestContext(request, {'ru': ru}) 包含 csrf_token?
  • 出于调试目的,进入你的中间件,你能print request.META["CSRF_COOKIE"] 吗?另外,如何转向真正的重定向?这将添加正确的推荐人。
  • “一组模板变量” - 使用真正的重定向并不能阻止任何这些,并且正如@danihp 提到的那样会添加正确的引用者(这很可能是问题所在)

标签: django


【解决方案1】:

来自wiki page关于CSRF:

跨站请求伪造,又称一键式攻击或 会话骑行 [...] 是一种对网站的恶意利用 从而未经授权的命令从用户传输 网站信任。

以后,在预防中:

验证请求的标头是否包含 X-Requested-With(使用 通过 v2.0 之前的 Ruby on Rails 和 v1.2.5 之前的 Django),或检查 HTTP Referer 标头和/或 HTTP Origin 标头。

实际上,您的 csrf 保护运行良好。因为,虽然我不是 100% 认为问题是缺少引荐来源网址,但我确实认为这是由于未使用触发 csrf 违规的正确重定向造成的。

解决方案 - 使用HttpResponseRedirect 并将信息传递给另一个视图。您可以将其作为 GET 数据传递:

 d = {'ru': ru, 'other': 'variables'}
 url = '/landing/?%' % '&'.join( map(lambda x: '='.join(x), d.items()) )
 return HttpResponseRedirect(url)

您还可以在 url 中使用正则表达式模式(如果有意义的话)或使用 sessions 如果其中有任何敏感内容。

【讨论】:

  • 是的,它有效。我也设法传递了模板变量。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2014-02-06
  • 1970-01-01
  • 2011-03-13
  • 2017-11-07
  • 1970-01-01
相关资源
最近更新 更多