博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSRF token的原理
阅读量:4946 次
发布时间:2019-06-11

本文共 2517 字,大约阅读时间需要 8 分钟。

参考:

http://www.cnblogs.com/zhaof/p/6281482.html 

 

简介

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect

原理

当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,这也是之前我们一直将其注释的原因,错误如下:

在django内部支持生成这个随机字符串

通过form提交

在form表单里面需要添加{%csrf_token%}

这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的

总结原理:当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功

cookie中存放的csrftoken如下图

 

通过ajax提交

因为cookie中同样存在csrftoken,所以可以在js中通过:

$.cooke("cstftoken")获取

如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典类型的数据,即这个时候需要一个key。

在views中的login函数中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME)

这里需要注意一个问题,这里导入的settings并不是我们在项目文件下看到的settings.py文件,这里是是一个全局的settings配置,而当我们在项目目录下的settings.py中配置的时候,我们添加的配置则会覆盖全局settings中的配置

print(settings.CSRF_HEADER_NAME)打印的内容为:HTTP_X_CSRFTOKEN

这里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以实际传递的是就是X_CSRFtoken,而在前端页面的ajax传递的时候由于不能使用下划线所以传递的是X_CSRFtoken

下面是在前端ajax中写的具体内容:

$("#btn1").click(function () {        $.ajax({            url:"/login/",            type:"POST",            data:{"usr":"root","pwd":"123"},            headers:{ "X-CSRFtoken":$.cookie("csrftoken")},            success:function (arg) {            }        })    })

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

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

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

这里的xhr是XMLHttpRequest的简写,ajax调用的就是这个方法

 

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

function csrfSafeMethod(method) {            // these HTTP methods do not require CSRF protection            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));        }        $.ajaxSetup({            beforeSend: function(xhr, settings) {                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {                    xhr.setRequestHeader("X-CSRFToken", csrftoken);                }            }        });

这样就实现了当GET|HEAD|OPTIONS|TRACE这些方式请求的时候不需要提交csrftoken

总结

1、    csrf在ajax提交的时候通过请求头传递的给后台的

2、    csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_,并且最后为HTTP_X_CSRFtoken

3、    csrf在form中提交的时需要在前端form中添加{%csrftoken%}

 

转载于:https://www.cnblogs.com/mengbin0546/p/9966431.html

你可能感兴趣的文章
多项式求ln,求exp,开方,快速幂 学习总结
查看>>
Linux下批量替换文件内容方法
查看>>
C++11带来的优雅语法
查看>>
WinForm无边框窗体依据任务栏位置最大化
查看>>
udp案例
查看>>
浅谈sql中的in与not in,exists与not exists的区别
查看>>
hdu 2018 母牛的故事 动态规划入门题
查看>>
22:LaunchMode应用场景
查看>>
bootstrap-table简单使用
查看>>
数组定义已经自动初始化
查看>>
List集合、泛型、装箱拆箱
查看>>
Dubbo知识点
查看>>
String类
查看>>
创建框架结构的页面
查看>>
Jquery实现遮罩层,就是弹出DIV周围都灰色不能操作
查看>>
Log4Net组件的应用详解
查看>>
跨域问题
查看>>
面试题33 把数组排成最小的数
查看>>
2014-05-07 总结
查看>>
排序算法
查看>>