day22-django csrf验证
一、引子
之前我们写代码,都是在settings 中,中间件,把csrf 注释掉,然我们请求post的时候会出现403
这个到底是啥用,它的原理是什么呢,我们这一回就来说它。
csrf 原理:
我们向服务器请求的时候,服务器认为你是GET 请求,服务器不仅把数据给你,还会偷偷的把一串加密的字符串给你,只有服务器能反解。当你再向服务器提交数据的时候,服务器就会找你要这个加密的字符串,验证你是否 是合法的,如果合法,才会处理你提交的数据,否则就弹出403 forbidden。
原理图:

二、from 表单提交方式
2.1、开启验证功能,之前注释的 csrf ,取消注释。

2.2、模板中,login.html

结果, 自动生成一个 不可见的 input 框,及一串字符。

2.3、get请求成cookie
说明:当我get请求的时候,我会自动在我的浏览器cookie生成一个值,然后相应的时候,服务器会返回这个cookie的值

所以,在input框之前添加{% csrf_toke %}的时候,不仅在form中生产一个隐藏的input框,而且请求get的时候,在本地cookie也会生产csrf的值,当然如果你在前端指向获取csfr_token的值,你就直接在前端获取就行了:
|
1
|
{{ csrf_token }} |
三、ajax
前面我们有学习过ajax 提交,那么ajax 需要怎么来携带 csrf_token呢?
1.html 前端
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 9 <form action="/login/" method="post"> 10 {% csrf_token %} 11 <input type="text" name="user"> 12 <input type="text" name="pwd"> 13 <p></p> 14 <input type="checkbox" name="rmb" value="1"> 10秒免登陆 15 <input type="submit" value="提交"> 16 <input type="button" value="ajax" id="btn"> 17 <input type="reset" value="取消"> 18 19 </form> 20 <span>{{ error_msg }}</span> 21 22 <script src="/static/jquery-1-12-4.js"></script> 23 <script src="/static/jquery.cookie.js"></script> 24 <script> 25 $(function(){ 26 var csrftoken=$.cookie("csrftoken"); 27 28 $("#btn").click(function(){ 29 $.ajax({ 30 url:"/login/", 31 typt:"POST", 32 data:{"user":"root","pwd":123}, 33 headers:{"X-CSRFtoken":csrftoken}, 34 sucess:function(arg){ 35 } 36 }) 37 }) 38 }) 39 </script> 40 </body> 41 </html>
那如果 ,有很多ajax 提交,是否需要每个都自己添加是否太麻烦,
下面我们来做一个全局添加,
1 //全局添加 2 $.ajax.Setup({ 3 beforeSend:function(xhr,settings){ 4 //xhr XML-HTTP-REQUEST 本质调用这个来发送ajax 5 xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken")) 6 } 7 });
如上面我们在 ajax 发送时,都加了csrf_token, 但是 如果get 请求,是不需要带,csrf_token,怎么设置呢?请看下面栗子
说明:当你点击 ajax 请求的时候, beforeSend, settings 可以拿到 $.ajax 的所有配置,其中包括 type ,这样我们就可以根据settings 的type 进行判断,如果是POST
才执行增加 scrf_token 的操作
1 // 四种请求方式不需要加csrf-token 2 function csrfSafeMethod(method){ 3 return(/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 4 } 5 6 $.ajax.Setup({ 7 beforeSend:function(xhr,settings){ 8 if(!csrfSafeMethod(settings.type) && !this.crossDomain){ 9 xhr.setRequestHeader("X-CSRFToken",csrftoken); 10 } 11 } 12 });
四、csrf 两个装饰器
我们在中间件中,启用了csrf 验证,但是有些 views 函数不需要验证怎么办
两个装饰器你 需要了解一下 csrf_exempt, csrf_protect
from django.views.decorators.csrf import csrf_exempt,csrf_protect


浙公网安备 33010602011771号