Django:Forbidden (403) CSRF verification failed. Request aborted. 解决之道

来源:互联网 发布:网络策划是什么 编辑:程序博客网 时间:2024/06/05 18:17

原文链接:http://blog.csdn.net/zgyulongfei/article/details/8830750


先让我还原一下错误页面:



今天被这个错误折腾了一上午,搞得我心力交瘁。网上搜索了很多答案,大致解决方案都是相同,我照着做,可是错误依然存在。

后来找jack帮忙才总算解决了这个问题。

原来我之前的方案一直是本末倒置,没有摸清楚django的csrf原理,就在那边瞎弄,浪费了很多时间。

下面我来说说我问题所在,如果你和我犯了同样的错误,可以做一下参考。


首先我做了一个test.html,如下:

[html] view plain copy
  1. <!DOCTYPE>  
  2. <html lang="zh-CN">  
  3.       
  4.     <head>  
  5.         <meta charset="utf-8">  
  6.         <title>  
  7.             test  
  8.         </title>  
  9.     </head>  
  10.       
  11.     <body>  
  12.         <form action="/postblog" method="post">  
  13.             {% csrf_token %}  
  14.             <input type="text" name="blog" />  
  15.             <input type="submit" value="发布" />  
  16.         </form>  
  17.     </body>  
  18.   
  19. </html>  

访问时候为 xx.xx.com/post,执行的方法为

[python] view plain copy
  1. def post_html(rq):  
  2.     return render_to_response("test.html")   

这个表单中已经包含了tag {% csrf_token %},这是网上解决方案中都说需要加上的标签。

点击【发布】按钮提交表单之后,执行/postblog操作,接下来看看服务端代码。

先在settings.py中加上

[python] view plain copy
  1. django.middleware.csrf.CsrfViewMiddleware  

[python] view plain copy
  1. MIDDLEWARE_CLASSES = (  
  2.     'django.middleware.common.CommonMiddleware',  
  3.     'django.contrib.sessions.middleware.SessionMiddleware',  
  4.     'django.middleware.csrf.CsrfViewMiddleware',  
  5.     'django.contrib.auth.middleware.AuthenticationMiddleware',  
  6.     'django.contrib.messages.middleware.MessageMiddleware',  
  7.     # Uncomment the next line for simple clickjacking protection:  
  8.     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',  
  9. )  

再看urls.py

[python] view plain copy
  1. url(r'^postblog$','postBlog')  

然后看views.py

[python] view plain copy
  1. def postBlog(rq):  
  2.     return render_to_response('ok.html', context_instance=RequestContext(rq))  

对于一个django初学者来说,一切都按照错误页面的Help中来做的啊,为什么结果还是错误的呢?

答:因为,,,从一开始的html页面就错了,而我在错误的前提下去做结果的补救,就救不回来了←_←


有经验的django开发者应该一眼就看得出错误的根源。

其实表单中的{% csrf_token %}在html页面被加载的时候就已经被赋值了,而post的时候需要将这个被赋值的csrf_token发送给服务端进行验证,如果验证成功才能进行post操作,否则就被认为是csrf攻击。

而上文中的test.html中一开始并没有由服务器给出一个csrf_token,在post的时候自然而然就不能成功验证。

而 context_instance=RequestContext(rq)的作用就是给这个csrf_token进行赋值,上文中却把赋值的操作在post之后进行,而正确地操作是在post之前打开html页面的时候就赋值。


所以只要修改post_html方法就行:

[python] view plain copy
  1. def post_html(rq):  
  2.     return render_to_response("test.html",context_instance=RequestContext(rq))   

以上。
阅读全文
0 0
原创粉丝点击