问题

在使用Django搭建好测试环境后,写了一个提交POST表单提交留言的测试页面。

如图:

填写表单,点击“提交留言”按钮提交到服务器,却出现

Forbidden (403)

CSRF verification failed. Request aborted.

由于之前使用GET方式提交表单内容测试均正常,就以为这个问题估计是配置问题没细看后边的帮助提示直接在网上搜索解决方案。

一搜索发现相关网页很多,看来大家都遇到过这个问题,想着应该很快能解决。

解决方案1:失败

在settings.py的MIDDLEWARE_CLASSES加入

'django.middleware.csrf.CsrfResponseMiddleware',

最终settings.py MIDDLEWARE_CLASSES 配置部分的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    # add
    'django.middleware.csrf.CsrfResponseMiddleware',
    # add end
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

保存,重新加载http://127.0.0.1/comment/add页面提交留言测试。

但在打开页面时出现500错误

赶紧看了一下控制台,发现如下错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Traceback (most recent call last):
  File "D:\Python27\lib\wsgiref\handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "D:\Python27\lib\site-packages\django\contrib\staticfiles\handlers.py", l
ine 67, in __call__
    return self.application(environ, start_response)
  File "D:\Python27\lib\site-packages\django\core\handlers\wsgi.py", line 219, i
n __call__
    self.load_middleware()
  File "D:\Python27\lib\site-packages\django\core\handlers\base.py", line 51, in
 load_middleware
    raise exceptions.ImproperlyConfigured('Middleware module "%s" does not defin
e a "%s" class' % (mw_module, mw_classname))
ImproperlyConfigured: Middleware module "django.middleware.csrf" does not define
 a "CsrfResponseMiddleware" class
[12/Sep/2012 11:00:35] "GET /comment/add/ HTTP/1.1" 500 59

大致的意思是我刚才在settings.py的MIDDLEWARE_CLASSES内添加的

'django.middleware.csrf.CsrfResponseMiddleware',

这个模块找不到,当时就有点郁闷了。网上一大堆都说是添加这个模块解决问题的,现在我本机上添加这个模块以后却提示没有找到模块?

为此,我重新把Django重新安装了一遍还是提示找不到模块。我只好到官网去看看手册,才发现Django新版已去掉这个模块。而我的Django正好是最新版本1.4只好放弃这个方案!

解决方案2:失败

在视图里使用@csrf_protect修饰

于是我在views.py文件里的add函数前加了@csrf_protect修饰符,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Create your views here.
# coding=utf-8
from django.shortcuts import render_to_response
import datetime
@csrf_protect
def add(request):
    dict={}
    if request.method=="POST":
        comment=request.POST.get('comment','')
        submit_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        dict.setdefault('comment',comment)
        dict.setdefault('submit_time',submit_time)
    return render_to_response("comment/add.html",dict)

打开留言页面发现又有一个错误提示

NameError at /comment/add/

name 'csrf_protect' is not defined

提示找不到我刚才添加的修饰符@csrf_protect,应该是没有导入相关模块的问题,于是在我的视图views.py头部添加了一句代码导入相关模块

from django.views.decorators.csrf import csrf_protect

保存文件,重新打开网页,错误已清除。心中一阵大喜,以为OK了。谁知提交留言以后还是提示

Forbidden (403)

CSRF verification failed. Request aborted.

有点急了,只好继续搜索其它解决方案

解决方案3:失败

在模板页的from表单标签内添加{% csrf_token %}

添加以后的代码如下

重新打开页面测试,依旧提示:

Forbidden (403)

CSRF verification failed. Request aborted.

有点火大了!

解决方案4:成功

一番折腾不能解决问题,于是只好冷静的查看错误页面的提示帮助。

第一个提示表示浏览器要开启cookie,我的是IE9浏览器,毋庸置疑默认是开启的。

第三个与第四个方案我都已测试过,唯独第二个方案我没有仔细研究。问题会不会在哪里呢?于是到官网文档寻找

The view function uses RequestContext for the template, instead of Context.

这句英文大致的意思是要在视图里使用RequestContext这个方法,最终在官网文档找到了以下解决方案

在return render_to_response函数里加入context_instance=RequestContext(request),代码如下:

return render_to_response("comment/add.html",dict,context_instance=RequestContext(request))

重新运行网页,又提示新的错误

NameError at /comment/add/

global name 'RequestContext' is not defined

提示找不到RequestContext,估计是我没有导入RequestContext模块,于是在把

from django.shortcuts import render_to_response

改写成

from django.shortcuts import render_to_response,RequestContext

视图整体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Create your views here.
# coding=utf-8
from django.shortcuts import render_to_response, RequestContext
import datetime
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def add(request):
    dict={}
    if request.method=="POST":
        comment=request.POST.get('comment','')
        submit_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        dict.setdefault('comment',comment)
        dict.setdefault('submit_time',submit_time)
    return render_to_response("comment/add.html",dict,context_instance=RequestContext(request))

重新运行网页正常,提交留言终于成功了

回顾优化

虽然折腾了半天才解决,但还是感觉有点糊里糊涂的。根据之前报错最后一条提示信息

If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

大致意思是如果settings.py的MIDDLEWARE_CLASSES里不开启CsrfViewMiddleware那么就必须要在视图里使用@csrf_protect模块修饰方法。我看看MIDDLEWARE_CLASSES里的设置,代码如下:

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

默认我的MIDDLEWARE_CLASSES已经给我开启了CsrfViewMiddleware这个模块。按照提示帮助,我可以把视图views.py里的修饰模块去掉应该也可以,于是注释了@csrf_protect修饰符与包含模块语句,最终代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Create your views here.
# coding=utf-8
from django.shortcuts import render_to_response, RequestContext
import datetime
# from django.views.decorators.csrf import csrf_protect
# @csrf_protect
def add(request):
    dict={}
    if request.method=="POST":
        comment=request.POST.get('comment','')
        submit_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        dict.setdefault('comment',comment)
        dict.setdefault('submit_time',submit_time)
    return render_to_response("comment/add.html",dict,context_instance=RequestContext(request))

测试成功!

什么是CSRF

问题是解决了,但我不禁回想为什么在Django里提交POST表单要配置那么麻烦(其实也不麻烦,但对新手来说就不一样了),于是搜索关键字看看,得知它是一种跨站请求伪造,黑客可以利用这个攻击站点。而Django里的使用这个机制就是防止CSRF模式攻击,原理大致是当你打开页面的时候产生一个csrftokey种下cookie,然后当你提交表单时会把本地cookie里的csrftokey值给提交服务器,服务器判断只有有效的csrftokey值才处理请求。

既然这样,我就查看了一下cookie信息,发现果真种了一个csrftokey值

右键HTML页面查看源代码,发现{% csrf_token %}位置替换成了一个input隐藏值

input隐藏标签值与cookie里的csrftoken值一致。

于是我做了一个测试,在from表单里把{% csrftoken %}标签直接替换成如上图的input标签,name与value保持一致,提交留言的时候服务器正常处理,测试成功。

不使用CSRF验证

Django提供了POST表单使用CSRF验证功能,感觉还是挺不错的。但在Django里能不能像普通的Form表单一样不使用CSRF验证功能呢?答案是肯定可以的。

1、我在settings.py的MIDDLEWARE_CLASSES把'django.middleware.csrf.CsrfViewMiddleware'注释

2、移出FROM表单里的{% csrf_token %}标记

3、不导入RequestContext模块,并把render_to_response()里的context_instance=RequestContext(request)去掉

重新运行网页测试提交留言正常。至此,应该可以判断出上边1步骤里的'django.middleware.csrf.CsrfViewMiddleware'语句开启了CSRF验证功能,默认是开启的,注释以后就关闭CSRF验证POST表单提交功能了。

Django POST CSRF verification failed. Request abor相关推荐

  1. Django错误解决: CSRF verification failed. Request abor

    2019独角兽企业重金招聘Python工程师标准>>> 该解决办法是根据个技术博文上修改后的,因以为原方法无法解决这个错误,以下内容是根据我实际操作过程修正的. Forbidden  ...

  2. Django web : CSRF verification failed. Request aborted.

    错误标题:CSRF verification failed. Request aborted. 错误描述: HelpReason given for failure:CSRF cookie not s ...

  3. Django 3.1.5, CSRF verification failed. Request aborted.

    post请求django的时候出现:CSRF verification failed. Request aborted 问题翻译: 一般而言,这可以发生时,有一个真正的跨站请求伪造,或当Django的 ...

  4. CSRF verification failed. Request aborted.的解决办法

    django1.21加入了防止CSRF攻击的模块. 这是django的debug模式下给出的错误提示页面. Forbidden (403) CSRF verification failed. Requ ...

  5. Python Django提交表单时报错:Forbidden (403) CSRF verification failed. Request aborted.

    报错截图: 解决方法: 把settings里面一个叫csrf的安全机制的注释掉即可. MIDDLEWARE = ['django.middleware.security.SecurityMiddlew ...

  6. CSRF verification failed. Request aborted.

    当运行一个django项目后,出现了这样的一个错误,如图: 这时我们只要在settings.py中注释掉一行即可. 'django.middleware.csrf.CsrfViewMiddleware ...

  7. CSRF verification failed. Request aborted. 表单提交方法为POST时的报错

    本人所用Django版本为1.11,在设置请求方法为POST时,遇到标题中的错误,尝试了多种方法,最终通过下面的操作来修复: 在template文件中添加图中红框部分 接着,导入csrf_exempt ...

  8. django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方案

    现象 表单界面如下: 在点击提交之后,出现如下错误页面: HTML的代码如下: contact_form.html <!DOCTYPE HTML PUBLIC ><html> ...

  9. 第九章 Django框架——csrf请求伪造和csrf_token使用

    第九章 Django框架--csrf请求伪造和csrf_token使用 一.csrf请求伪造 二.csrf_token使用 三.简单的csrf_token应用 四.Ajax使用csrf_token 一 ...

最新文章

  1. [Git高级教程 (一)] 通过 Tag 标签回退版本修复 bug
  2. java 压缩二进制流_Java:自己动手写压缩软件,超详细解释(哈夫曼实现)
  3. python中修饰器_python 中的修饰器
  4. 每日一道算法题--leetcode 169--求众数--python--两种方法
  5. 屏幕录像专家 V6.0+注册机
  6. html表格的形式制作调查问卷,问卷调查表格式,问卷调查怎么制作?
  7. 【网络与信息安全】 2019年-中国计算机学会推荐国际学术会议和期刊目录(三)
  8. 微信小程序源代码_下厨房菜谱APP
  9. airdrop搜不到对方_如何将AirDrop图标添加到您的macOS Dock
  10. 弹出框样式,swal is not define
  11. 骨传导原理是什么?骨传导耳机对保护耳朵健康有帮助吗?
  12. 运营版uniapp多商户商城小程序+H5+APP+商家入驻短视频社区种草直播阶梯拼团
  13. JavaWeb开发 —— HTML
  14. 【管理】需求分析与软件设计|需求分析报告和需求规格说明书的区别
  15. 图像处理1--傅里叶变换(Fourier Transform )
  16. jeesite(一)
  17. zuk android os 流量,ZUK Z1国际版:细数Cyanogen OS的几点不同
  18. The road you are trudging is bound for loneliness.(前行的道路注定孤独)
  19. 广告推荐系统—CTRLR模型评价
  20. 在收到面试通知的电话时,该问哪些问题?

热门文章

  1. [九度][何海涛] 矩形覆盖
  2. 极致通缩和永动机模型,将推动 PlatoFarm 爆发
  3. 未来五年,不懂人工智能的程序员会被淘汰吗?
  4. Atcoder ABC276 A-E
  5. 扔鸡蛋问题(四种解法)
  6. 凡客:成于营销,败于营销
  7. 使用Qt实现计算器功能
  8. 【经典】非全序列底板通俗演义-AC OC EG CL 红黑碳王
  9. 数据库sqlite3的安装与应用
  10. Mac开发必备工具(一)—— Homebrew