现象:
Forbidden (403)
CSRF verification failed. Request aborted.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
- Your browser is accepting cookies.
- The view function uses
RequestContext
for the template, instead ofContext
. - In the template, there is a
{% csrf_token %}
template tag inside each POST form that targets an internal URL. - If you are not using
CsrfViewMiddleware
, then you must usecsrf_protect
on any views that use thecsrf_token
template tag, as well as those that accept the POST data.
解决方法:
1. 在template里面的form后面添加 {% csrf_token %}
2. 注意setting.py里面
MIDDLEWARE_CLASSES = (
...
'django.middleware.csrf.CsrfViewMiddleware',
)
3. 在view里面
from django.template import RequestContext
def register(request):
return render_to_response(register.html', context_instance=RequestContext(request))
2013.3.12
又出现了同样的问题,更为恼人的是用上面的方法解决不了。
情况是这样:
view中
func1 跳转到 func.html
在func.html中的form post到another.html, 经过view中的func2。
按照上面的方法,给func.html设置了{% csrf_token %}, 给func2也使用了RequestContext。
但就是不能达到预期效果。
后来对比上次的login.html和func.html源码,发现func.html少一个名为csrfmiddlewaretoken的hidden域。
于是想到会不会是从func1函数跳转过来时的问题,果然,在那个函数里用的是Context而不是RequestContext,改一下就ok了。
所以结论:
使用csrf时,说的RequestContext代替Context指的是view里面跳到该template的那个function
参考:
http://stackoverflow.com/questions/4547639/django-csrf-verification-failed