Django 中CSRF中间件 'django.middleware.csrf.CsrfViewMiddleware',
2024-08-30 04:56:01
1、Django中CSRF中间件的工作原理及form表单提交需要添加{% csrf_token %}防止出现403错误
CSRF # 表示django全局发送post请求均需要字符串验证
功能:防止跨站请求伪造的功能
工作原理:客户端访问服务器端,在服务器端正常返回给客户端数据的时候,而外返回给客户端一段字符串,等到客户端下次访问服务器
端时,服务器端会到客户端查找先前返回的字符串,如果找到则继续,找不到就拒绝。
访问流程:客户端-》URL路由系统 - 》 CSRF -》视图函数
需要在客户端页面的post表单内添加:{% csrf_token %}
全局生效:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部生效:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
写法如下:
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def index(request): # 这样表示此函数取消CSRF验证 2、Django中使用ajax做post提交防止出现403错误的方法
现在以ajax发送一个请求,注意get和post的区别,post会被forbidden,get不会,
url 文件
from django.conf.urls import url
from django.contrib import admin from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^ajax_send/', views.ajax_send),
]
在views文件中,
def ajax_send(request): return HttpResponse("ok")
在前端页面,,
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> <script src="{% static 'jquery-3.2.1.js' %}"></script> </head>
<body> <button>ajax发送</button> </body> <script> $("button").click(function () { $.ajax({
url:"/ajax_send/",
data:{"user":"gu"},
type:"POST", ----------如果以get请求是不会被forbidden,只有post请求会被forbidden,
success:function (data) {
alert(data)
} }) }) </script> </html>
ajax的post请求会报错,forbidden
Forbidden (CSRF token missing or incorrect.): /ajax_send/
[10/Dec/2017 10:58:41] "POST /ajax_send/ HTTP/1.1" 403 2502
Forbidden (CSRF token missing or incorrect.): /ajax_send/
[10/Dec/2017 10:59:22] "POST /ajax_send/ HTTP/1.1" 403 2502
Forbidden (CSRF token missing or incorrect.): /ajax_send/
如果想要避免forbidden,
方法1:要在ajax发送请求前加上
$.ajaxSetup({
data:{csrfmiddlewaretoken:'{{ csrf_token }}'},
}); 注意:{{ csrf_token }} ,是需要渲染的,不能脱离模板,所以是外部文件引入的话,不能执行,
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> <script src="{% static 'jquery-3.2.1.js' %}"></script> </head>
<body> <button>ajax发送</button> </body> <script> $("button").click(function () { $.ajaxSetup({
data:{csrfmiddlewaretoken:'{{ csrf_token }}'},---------
}); $.ajax({ url:"/ajax_send/",
data:{"user":"gu"},
type:"POST",
success:function (data) {
alert(data)
} }) }) </script> </html>
方法2:在ajax发送请求是加上csrfmiddlewaretoken,的值,
$.ajax({ url:"/ajax_send/",
data:{"user":"gu","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},-----与方法1的功能一样,
但这种方法可以作为一个外部文件引入,
type:"POST",
success:function (data) {
alert(data)
} }) })
-------
方法3:修改header,
在views打印cookie可以得到csrftoken
def index(request): print("cookie",request.COOKIES)
#cookie {
# 'csrftoken': 'AB9v1MGTbdpSGg3FaGCIiUxrKVR8zKSqgdGFDn5E0ADsJ2ST7N2zgW6KboQ8G31x',
# 'sessionid': 'eexw5p38vky9qo38nf372dz5lj1br6xf'
# }
#cookie 是浏览器给的, return HttpResponse("index")
需要先下载一个jquery.cookie.js插件文件,然后引用,
<script src="{% static 'jquery.cookie.js' %}"></script>
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> {# <script src="{% static 'jquery-3.2.1.js' %}"></script>#}
<script src="{% static 'jquery.cookie.js' %}"></script> </head>
<body> {#<form action="/login/" method="post">#}
{# csrf_token 在前端会渲染出一个input标签,是一组键值对,键是csrfmiddlewaretoken,值是随机字符串,会随着下面的input标签一起提交,只有这种形式发送post的请求才能被接收,#}
{##}
{# {% csrf_token %}#}
{# <p>用户名:{{ form_obj.user }}</p>#}
{# <p>密 码:{{ form_obj.pwd }}</p>#}
{# <input type="submit">#}
{##}
{#</form>#} <button>ajax发送</button> </body> <script> {# $("button").click(function () {#}
{##}
{# $.ajaxSetup({#}
{# data:{csrfmiddlewaretoken:'{{ csrf_token }}'},#}
{# });#}
{##}
{# $.ajax({#}
{##}
{# url:"/ajax_send/",#}
{# data:{"user":"gu","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},#}
{# type:"POST",#}
{# success:function (data) {#}
{# alert(data)#}
{# }#}
{##}
{#{)#} $('button').click(function () { $.ajax({
url:"/ajax_send/",
type:"post",
headers:{"X_CSRFToken":$.cookie('csrftoken')},---------------
success:function () {
alert(123)
} })
}) </script> </html>
-----
input 标签的上传文件,
在前端页面
{#发送文件的时候,要加上enctype ,是以块的方式发送文件,#}
<form action="/login/" method="post" enctype="multipart/form-data">
<input type="file" name="fileobj"> </form> <button>ajax发送</button>
在views文件中,获取文件,保存文件,
def login(request): if request.method == "POST": print("post",request.POST.get("fileobj"))
print("post",type(request.POST.get("fileobj")))
print("===",request.FILES) fileobj = request.FILES.get("fileobj") #创建一个文件句柄,把文件存起来,
f=open(fileobj.name,'wb') for i in fileobj.chunks():#按块存
f.write(i)
最新文章
- ActiveMQ(li)
- socket编程报异常java.io.EOFException
- iOS - UIDatePicker
- I.MX6 Android 5.1 快速合成系统
- C#垃圾回收机制
- 测试浏览器最多能包含Cookie的个数和Cookie中包含的最多内容
- 我新买的红米手机,新浪和360浏览器都能进,也能看电视,就是不能上手机QQ和微信
- 开源软件授权协议详解(GPL/MPL/LGPL/BSD/Apache Licence/Creative Commons/MIT)
- mybatis08
- Linux命令:TOP
- JavaScript一个google地图获取
- Tomcat开启SSL协议支持
- EF core2.1+MySQL报错&#39;Void Microsoft.EntityFrameworkCore.Storage.Internal.RelationalParameterBuilder..ctor(Microsoft.EntityFrameworkCore.Storage.IRelationalTypeMapper)
- !!!常用CSS代码
- Golang入门教程(十四)结构体和类详解
- git 配置 BeyondCompare
- AICODER官方小程序和公众号上线了
- 写一份简单的webpack2 的配置文件,无比简单
- 连接Hive的客户端界面工具–SQuirrel SQL Client
- Swift5 语言参考(一) 关于语言参考