-
csrf跨站请求伪造
-
csrf相关校验策略
-
CBV添加装饰器的多种方式
csrf跨站请求伪造
钓鱼网站:模仿一个正规网站,让用户在该网站上进行操作,但操作的结果会影响到正常的网站账户,但是其中有一些猫腻
eg:英语四六级考试需要网上先缴费 但是你会发现卡里的钱扣了但是却交到了一个莫名其妙的账户 并不是真正的四六级官方账户
模拟钓鱼网站案例:转账案例
# 真网站:
'''view.py'''
def transfer_func(request):
if request.method == 'POST':
username = request.POST.get('username')
target_name = request.POST.get('target_name')
money = request.POST.get('money')
print(f'{username}给{target_name}转了{money}')
return render(request, 'transferPage.html')
'''transfer.html'''
<body>
<h1>这是一个真网站</h1>
<form action="" method="post">
<p>用户名:
<input type="text" name="username">
</p>
<p>转账人:
<input type="text" name="target_name">
</p>
<p>转账金额:
<input type="text" name="money">
</p>
<input type="submit">
</form>
</body>
# 假网站:
'''view.py'''
def transfer_func(request):
if request.method == 'POST':
username = request.POST.get('username')
target_name = request.POST.get('target_name')
money = request.POST.get('money')
print(f'{username}给{target_name}转了{money}')
return render(request, 'transferPage.html')
'''transfer.html'''
<body>
<h1>这是一个假网站</h1>
<form action="http://127.0.0.1:8000/transfer/" method="post">
<p>用户名:
<input type="text" name="username">
</p>
<p>转账人:
<input type="text">
<input type="text" name="target_name" value="黑客小赵" style="display: none">
</p>
<p>转账金额:
<input type="text" name="money">
</p>
<input type="submit">
</form>
</body>
csrf校验策略
网站区分请求页面是真还是假的途径,是给真的提交数据的页面添加一个唯一标识
# form表单中添加csrf唯一标识
在html页面上的form表单内部添加{% csrf_token %} 这样settings校验csrf的那句中间件就可以不用再注掉,凭借中间件就可以想页面发送请求
即使在假的页面上添加唯一标识 那也是假页面的唯一标识 无法向真的页面发送请求
# Ajax请求添加唯一标识
方式1:
自己动手取值 较为繁琐
data:{'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
方式2:
利用模板语法自动获取(一定要用引号引起来)
data:{ 'csrfmiddlewaretoken':'{{ csrf_token }}','username':'jason'},
方式3:
引入外部cs文件
在django项目中新建静态文件static,在settings.py中加入以下代码:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
在static中新建一个js文件,在js文件中加入以下代码:
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);
}
}
});
在加入ajax中的script标签中加入:src="/static/myjs.js"
csrf相关装饰器
整个django项目都校验csrf 但是某些个视图函数\类不想校验
整个django项目都不校验csrf 但是某些个视图函数\类需要校验
这种效果我们可以通过装饰器实现
# FBV添加装饰器:
导入模块,直接将相关装饰器添加在相关视图函数上面即可
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_exempt:整个django项目要校验csrf,被装饰的函数不校验
@csrf_protect:整个django项目不校验csrf,被装饰的函数要校验
# CBV添加装饰器:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django import views
from django.views.decorators.csrf import method_decorator
方式1:导入模块,在相应函数上面添加@method_decorator(csrf_protect) # 全局不校验,指定函数校验
class Myclass(views.View):
def get(self, request):
return render(request, 'CBV.html')
@method_decorator(csrf_exempt)
def post(self, request):
return HttpResponse('哈哈哈')
方式2:导入模块,在类上面添加该装饰器,用name指定需要添加的函数名:
@method_decorator(csrf_protect, name='post')
class Myclass(views.View):
def get(self, request):
return render(request, 'CBV.html')
def post(self, request):
return HttpResponse('哈哈哈')
方式3:导入模块,在类中dispatch方法上添加装饰器,该方法对类中所有方法都有效:
class Myclass(views.View):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self, request):
return render(request, 'CBV.html')
'''
注意有一个装饰器是特例只能有一种添加方式>>>:csrf_exempt
只有在dispatch方法添加才会生效
'''
标签:跨站,return,get,request,校验,添加,CBV,csrf
From: https://www.cnblogs.com/super-xz/p/17011162.html