【问题标题】:Django: csrf verification errorDjango:csrf验证错误
【发布时间】:2014-09-09 16:27:48
【问题描述】:

GET 请求:

<WSGIRequest
path:/contact,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{'__utma': '96992031.1421967427.1405088230.1405685996.1405688035.8',
 '__utmb': '96992031.3.10.1405688035',
 '__utmc': '96992031',
 '__utmz': '96992031.1405088230.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
 'djdt': 'hide'},
META:{'CONTENT_LENGTH': '',
 'CONTENT_TYPE': '',
 u'CSRF_COOKIE': u'RRNKQhMUwb2blNVeLxV61A8gqTbuFXya',
 'HTTP_ACCEPT': 'text/html, */*; q=0.01',
 'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
 'HTTP_ACCEPT_LANGUAGE': 'en-GB,en-US;q=0.8,en;q=0.6',
 'HTTP_CONNECTION': 'keep-alive',
 'HTTP_COOKIE': 'djdt=hide; __utma=96992031.1421967427.1405088230.1405685996.1405688035.8; __utmb=96992031.3.10.1405688035; __utmc=96992031; __utmz=96992031.1405088230.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
 'HTTP_HOST': '127.0.0.1:8000',
 'HTTP_REFERER': 'http://127.0.0.1:8000/',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36',
 'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
 'PATH_INFO': u'/contact',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_PORT': 57435,
 'REQUEST_METHOD': 'GET',
 'SCRIPT_NAME': u'',
 'SERVER_NAME': '127.0.0.1',
 'SERVER_PORT': '8000',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'Werkzeug/0.9.6',
 'werkzeug.request': <BaseRequest 'http://127.0.0.1:8000/contact' [GET]>,
 'werkzeug.server.shutdown': <function shutdown_server at 0x25876e0>,
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f72b9132270>,
 'wsgi.input': <socket._fileobject object at 0x7f72b0132cd0>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}>

发布请求:

<WSGIRequest
path:/contact,
GET:<QueryDict: {}>,
POST:<QueryDict: {u'city': [u'London'], u'first_name': [u'', u'', u''], u'future-notices-name': [u''], u'email_psp': [u'm'], u'csrfmiddlewaretoken': [u'RRNKQhMUwb2blNVeLxV61A8gqTbuFXya'], u'email': [u''], u'wfax': [u'+44 (0)']}>,
COOKIES:{'__utma': '96992031.1421967427.1405088230.1405685996.1405688035.8',
 '__utmb': '96992031.3.10.1405688035',
 '__utmc': '96992031',
 '__utmz': '96992031.1405088230.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
 'csrftoken': 'RRNKQhMUwb2blNVeLxV61A8gqTbuFXya',
 'djdt': 'hide'},
META:{'CONTENT_LENGTH': '627',
 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
 u'CSRF_COOKIE': u'RRNKQhMUwb2blNVeLxV61A8gqTbuFXya',
 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
 'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
 'HTTP_ACCEPT_LANGUAGE': 'en-GB,en-US;q=0.8,en;q=0.6',
 'HTTP_CACHE_CONTROL': 'max-age=0',
 'HTTP_CONNECTION': 'keep-alive',
 'HTTP_COOKIE': 'djdt=hide; __utma=96992031.1421967427.1405088230.1405685996.1405688035.8; __utmb=96992031.3.10.1405688035; __utmc=96992031; __utmz=96992031.1405088230.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); csrftoken=RRNKQhMUwb2blNVeLxV61A8gqTbuFXya',
 'HTTP_HOST': '127.0.0.1:8000',
 'HTTP_ORIGIN': 'http://127.0.0.1:8000',
 'HTTP_REFERER': 'http://127.0.0.1:8000/',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36',
 'PATH_INFO': u'/contact',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_PORT': 57438,
 'REQUEST_METHOD': 'POST',
 'SCRIPT_NAME': u'',
 'SERVER_NAME': '127.0.0.1',
 'SERVER_PORT': '8000',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'Werkzeug/0.9.6',
 'werkzeug.request': <BaseRequest 'http://127.0.0.1:8000/contact' [POST]>,
 'werkzeug.server.shutdown': <function shutdown_server at 0x7f72b0128aa0>,
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f72b9132270>,
 'wsgi.input': <socket._fileobject object at 0x7f72b02500d0>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}>

views.py

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            return HttpResponse(json.dumps(cd))
    else:
        form = ContactForm()
    return render(request, 'contact.html', {'form': form})

表格如下:

<form id="notice_form" action="/contact" method="post">{% csrf_token %}

...

我正在尝试提交表单,但收到 403 禁止错误。 检查 get/post 请求,我可以看到两个请求中的 csrftoken cookie 相同。那为什么它仍然给我那个错误? :(

【问题讨论】:

  • 你能发布&lt;form&gt; HTML sn-p吗?
  • 我编辑了我的帖子以包含表单的一部分(它以通常的方式使用,没有什么不同)。
  • 你启用 CSRF 中间件了吗?
  • 是的,它在我的设置中 (django.middleware.csrf.CsrfMiddleware)
  • 你能看看你的日志吗?我可以看到一个错误'wsgi.errors': &lt;open file '&lt;stderr&gt;', mode 'w' at 0x7f72b9132270&gt;,,但不知道它到底是什么或为什么。

标签: python django django-forms csrf django-csrf


【解决方案1】:

根据 Django 文档(因为我几乎从不使用基于函数的视图): https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#how-to-use-it

在相应的视图函数中,确保 'django.core.context_processors.csrf' 上下文处理器正在被使用。 通常,这可以通过以下两种方式之一完成:

使用 RequestContext,它总是使用 'django.core.context_processors.csrf'(不管你的 TEMPLATE_CONTEXT_PROCESSORS 设置)。如果您使用通用视图 或 contrib 应用程序,你已经被覆盖了,因为这些应用程序使用 RequestContext 贯穿始终。

问题是您使用的是不使用 RequestContext 的 HttpResponse,因此您需要移至另一个解决方案或从 csrf 中排除视图(我不喜欢这样)。 如果您将其用作 ajax 请求,请确保您实现: https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#ajax

【讨论】:

  • 即使我使用render 或render_to_response(带有RequestContext)也没有任何变化:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 2013-02-17
  • 1970-01-01
  • 2018-09-05
  • 2011-07-08
  • 2014-04-11
  • 2013-02-18
相关资源
最近更新 更多