准备

现有如下模板和视图:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/login/" method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="text" name="password"></p>
<p><input type="submit" value="提交"></p>
<p style="color: red"> {{ msg }}</p>
</form>
</body>
</html>

login.html

 from django.shortcuts import render,HttpResponse

 def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
print(username, password)
return HttpResponse('登陆成功')
else:
return render(request, 'login.html')

views.py

使用

表单提交

使用上述模板中表单直接进行提交时,会发现会返回403错误如下:

这是因为Django中默认配置了一个拦截CSRF请求的中间件,在settings.py中可配置:

 MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', # 此项便是拦截CSRF请求的中间件
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

settings.py

  • 方案一:去除该中间件(不推荐)

    直接注释该行即可。

     MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware', # 此项便是拦截CSRF请求的中间件
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    setting.py

    注释之后就可以正常提交请求了。

  • 方案二:表单中添加csrf_token

     <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    </head>
    <body>
    <form action="/login/" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="username"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit" value="提交"></p>
    <p style="color: red"> {{ msg }}</p>
    </form>
    </body>
    </html>

    login.html

    在表单中添加上‘{%csrf_token%}’之后,查看网页源代码会发现表单中多了一个隐藏的输入框,如下:

    Django通过这种方式让表单的请求带着token一起发送到服务器去验证。

Ajax请求

修改login.html内容如下:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<script src="/static/jquery.min.js"></script>
</head>
<body>
<script>
function login() {
$.ajax({
url: "/login/",
type: "POST",
data: {"usr": "admin", "pwd": "123"},
{#headers:{ "X-CSRFtoken":$.cookie("csrftoken")},#}
success: function (data) {
alert(data)
}
})
}
login()
</script>
</body>
</html>

login.html

访问该页面会发现与表单请求一样被拦截:

  • 方案一:headers中携带csrf_token

     <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    <script src="/static/jquery.min.js"></script>
    </head>
    <body>
    <script>
    function login() {
    $.ajax({
    url: "/login/",
    type: "POST",
    data: {"usr": "admin", "pwd": "123"},
    headers: {
    "X-CSRFtoken": '{{csrf_token}}'
    },
    success: function (data) {
    alert(data)
    }
    })
    }
    login()
    </script>
    </body>
    </html>

    login.html

  • 方案二:data中携带csrf_token

     <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    <script src="/static/jquery.min.js"></script>
    </head>
    <body>
    {% csrf_token %}
    <script>
    function login() {
    $.ajax({
    url: "/login/",
    type: "POST",
    data: {"usr": "admin", "pwd": "123", "csrfmiddlewaretoken": '{{csrf_token}}'},
    success: function (data) {
    alert(data)
    }
    })
    } login()
    </script>
    </body>
    </html>

    login.html

补充

全局添加csrf_token

如果页面中有多个ajax请求的话就可以通过下面方式在所有的ajax中添加headers信息:

$.ajaxSetup({
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("X-CSRFtoken", '{{csrf_token}}')
}
});

这样就会在提交ajax之前执行这个方法,从而在所有的ajax里都加上这个csrftoken。

仅post提交添加csrf_token

如果想要实现在当get方式的时候不需要提交csrftoken,当post的时候需要,实现这种效果的代码如下:

function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} $.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", '{{ csrf_token }}');
}
}
});

上述示例因csrf_token都是通过模板语言取出,所以html页必须由django的render函数渲染过。同理也可通过js取出cookie中csrf_token值,填充到对应位置即可。

指定视图函数不校验csrf

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def view_func(request):
pass

python框架之Django(9)-CSRF的更多相关文章

  1. python框架之django

    python框架之django 本节内容 web框架 mvc和mtv模式 django流程和命令 django URL django views django temple django models ...

  2. 第六篇:web之python框架之django

    python框架之django   python框架之django 本节内容 web框架 mvc和mtv模式 django流程和命令 django URL django views django te ...

  3. Python框架之Django学习

    当前标签: Django   Python框架之Django学习笔记(十四) 尛鱼 2014-10-12 13:55 阅读:173 评论:0     Python框架之Django学习笔记(十三) 尛 ...

  4. Python框架之Django的相册组件

    Python框架之Django的相册组件 恩,没错,又是Django,虽然学习笔记已经结贴,但是学习笔记里都是基础的,Django的东西不管怎么说还是很多的,要学习的东西自然不会仅仅用十几篇博文就能学 ...

  5. Python高级进阶(二)Python框架之Django写图书管理系统(LMS)

    正式写项目准备前的工作 Django是一个Web框架,我们使用它就是因为它能够把前后端解耦合而且能够与数据库建立ORM,这样,一个Python开发工程师只需要干自己开发的事情就可以了,而在使用之前就我 ...

  6. Python自动化之Django的CSRF

    什么CSRF? CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到你的网站上了,那么当这个 ...

  7. python框架之Django(11)-中间件

    介绍 在django中,中间件其实就是一个类,在一个请求到来和这个请求结束之前,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项目的settings模块中,有一个 M ...

  8. Python框架之Django学习笔记(十一)

    话说上次说到数据库的基本访问,而数据库我们主要进行的操作就是CRUD,也即是做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete),俗 ...

  9. Python框架之Django学习笔记(十二)

    Django站点管理 十一转眼结束,说好的充电没能顺利开展,反而悠闲的看了电视剧以及去影院看了新上映的<心花路放>.<亲爱的>以及<黄金时代>,说好的劳逸结合现在回 ...

随机推荐

  1. 转:slf4j-api、slf4j-log4j12、log4j之间关系

    原文:https://www.cnblogs.com/lujiango/p/8573411.html 1. slf4j-api slf4j:Simple Logging Facade for Java ...

  2. 基于Vue element-ui实现支持多级纵向动态表头的仿表格布局

    [本文出自天外归云的博客园] 需求图示如下,多级纵向动态表头表格: 我的思路是用element-ui的layout实现,做出一个仿造表格,能够支持动态的.多级的.纵向的表头: <template ...

  3. 用VSCode写Vue要用到的配置

    [本文出自天外归云的博客园] 文件-首选项-设置-打开settings.json-用户设置区域填写: { "workbench.colorTheme": "Monokai ...

  4. iOS 实现单个页面支持横竖屏,其他页面只能竖屏

    最近在自己的项目里面 有需要做一个需求 : app中某一个页面支持横竖屏, 而其他页面只能竖屏. 1 2 实现方法如下: 1 首先需要Xcode中选中支持的屏幕方向  2 Appdelegate中 . ...

  5. 【iCore4 双核心板_uC/OS-II】例程十:信号量集

    一.实验说明: 在实际应用中,任务常常需要与多个事件同步,即要根据多个信号量组合作用的结果来决定任务的运行方式.UCOSII为了实现多个信号量组合的功能定义了一种特殊的数据结构——信号量集. 二.实验 ...

  6. 快速入门 WePY 小程序【转】

    一.WePY介绍 WePY 是 腾讯 参考了Vue 等框架对原生小程序进行再次封装的框架,更贴近于 MVVM 架构模式, 并支持ES6/7的一些新特性. 二.WePY 使用 1.WePY的安装或更新都 ...

  7. Web 呼起 APP

    1. iOS iOS 9+,用 universal links,可以在微信和 safari 中呼起 APP,并定位到指定 View iOS 8-,用 iframe + scheme,在微信中不可以呼起 ...

  8. Geoserver GeoWebCache 切图失败 This requested used more time than allowed and has been forcefully stopped. Max rendering time is 60.0s

    错误信息: This requested used more time than allowed and has been forcefully stopped. Max rendering time ...

  9. 使用cnpm 安装vue.js

    前提已经安装了node.js 一.临时使用 1.npm install -g cnpm --registry=https://registry.npm.taobao.org 2.cnpm instal ...

  10. linux如何添加telnet服务

    一.安装telnet 1.检测telnet-server的rpm包是否安装 [root@localhost ~]# rpm -qa telnet-server 若无输入内容,则表示没有安装.出于安全考 ...