CSRF跨站请求伪造
架设我的网站:
<a href=''>点我</a>
cfrf1.html
<form method="POST" action='/csrf1.html'>
<input type="text" name="user" />
<input type="submit" value="提交" />
</form>
之前在settings.py中,将MIDDLEWARE中的:
django.middleware.csrf.CsrfViewMiddleware
这行给予注释掉,相当于不做跨站请求伪造验证,再次去掉注释,使得CSRF生效,自动生成随机字符串,后台中间件开始验证。即使不显示写明验证操作。
但可以模板中加上:
{% csrf_token %}
加在form表单中,可以在页面源码中看到随机字符串。
如果加上:
{ csrf_token }这时只会生成随机字符串,不会生成input框。
CSRF中间件还会在表单中使用随机字符串,在cookie中也增加CSRF字符串。
一般的网站都会带CSRF验证字符串。例如github.com。如果不加,不能称为成功的网站。
这时最简单的使用,如果注释掉CSRF中间件,表示整个网站不再验证CSRF。另外也可以局部禁用:
对不使用CSRF验证的函数,增加装饰器:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf1():
....
这样,对csrf1函数不再使用CSRF验证。注意,局部禁用的时候,必须在settings中使用CSRF中间件。
另外,也可局部使用:
from django.views.decorators.csrf import csrf_protect
装饰器
@csrf_protect表示使用CSRF的函数。此时,可以在设置中注释掉CSRF中间件。
在CBV类型的网站中:
from django.views import view
class Foo(view):
def get(self,request):
pass
此时上述装饰器只能在类前加,在类中方法不允许使用上述装饰器。
from django.utils.decorators import method_decorator
@method_decorator(csrf_protect)
使用上述装饰器的使用方法,可以使用在类上或者类的方法上。
def wrapper(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
这是典型的写装饰器的方法,只能使用Django的方法。
@method_decorator(warpper,name='get')
这种装饰器,仅对get函数进行装饰。
@method decorators(warpper,name='dispath')
对该类的所有函数进行装饰。
CSRF,装饰器必须加在类上,不能加在类中方法上。
AJAX中的CSRF:
<a onclick="submitForm">Ajax提交</a>
<script src='/static/jquery-1.12.4.js"></script>
<script>
function submitForm(){
$var csrf=('input[name="csrfmiddlewaretoken"]'.val();获取csrf值,input标签中
var user=$('#user').val();获取user值
$.ajax({
url:'/csrf1.html',
type:'POST';
data:{"user":user,'csrfmiddlewaretoken':csrf}
success:function(arg){
console.log(arg);}
})
ajax发送请求数据时,必须加上csrfmiddlewaretoken值,这是Django自动生成的input标签name。
Ajax提交数据时,携带CSRF,有两种方法。以上是第一种方法,在data中携带中间件控件值。
以下是第二种方法:把cookie传输过去:
名称是csrftoken,通过JS可以获取到本地浏览器的cookie:
顺便学习一下,jquery.cookie.js是个插件,可以解析cookie数据。注意这个插件依赖jquery。
js中,获取cookie的方法:
document.cookie,此时拿到字符串'csrftoken=XXXXX',需要自行解析字符串。
使用上述插件,可以直接获取cookie值:
$.cookie('csrftoken')
另外,可以设置$.cookie('cookiename','cookievalue'),设置cookie值。
<script>
function submitForm(){
var token = $$.cookie('cstftoken');
var user=$('$user').val();
$.ajax({
url:'/cstf1.html',
type:'POST',
data:{"user":user,'csrfmiddlewaretoken':csrf),
success:function(arg){
console.log(arg);
}
}
})
}
cookie要添加到请求头中,这是Django中的定义。ajax中如何添加请求头:
<script>
function submitForm(){
var token = $$.cookie('cstftoken');
var user=$('$user').val();
$.ajax({
url:'/cstf1.html',
type:'POST',
hearders:{'X-CSRFToken':token},
data:{"user":user),
success:function(arg){
console.log(arg);
}
}
})
}
csrf要值,一是在数据中带过去,二是在请求头中传输过去,两者取其一,将值传过去即可。
另外需要说明的是:
<script src="/static/jquery.cookie.js"></script>这个JS文件将操作cookie的函数进行了打包,不必再自行进行分割等操作。