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

  

 

 


 

posted @ 2018-07-23 16:38  东郭仔  阅读(139)  评论(0)    收藏  举报