Day49 of learning python -- 跨站伪造请求CSRF
一、跨站请求伪造简介
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
因此在提交服务器请求时,中间件需要客户端验证是否带有一个csrf字符串,通过该字符串来判断请求是否合法的,服务器才会做下一步操作。
全局:
在Django框架下,默认是启动中间件的:django.middleware.csrf.CsrfViewMiddleware
局部:
1)@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
在setting下,注释中间件 在views.py视图函数下 from django.views.decorators.csrf import csrf_protect @csrf_protect def csrf1(request): if request.method == 'GET': return render(request,'csrf1.html') else: return HttpResponse('ok')
2)@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
在setting下,使用中间件 在views.py文件下 from django.views.decorators.csrf import csrf_exempt @csrf_exempt def csrf1(request): if request.method == 'GET': return render(request,'csrf1.html') else: return HttpResponse('ok')
二、应用
在启动防跨站请求伪造功能时,由于需要客户端带一个csrf字符串。而这个字符时,客户端首次登陆服务器时,会下发的,通过{% csrf_token %}得到
1)对于普通表单
由于普通表单在提交POST请求时,如果设置了{% csrf_token %},会有"submit"提交上去,urls.py:re_path('^csrf1.html$',views.csrf1)
views.py def csrf1(request): if request.method == 'GET': return render(request,'csrf1.html') else: return HttpResponse('ok')
csrf1.html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>csrf1</title> </head> <body> <form action="/csrf1.html" method="post"> {% csrf_token %} <input id="user" type="text" name="user"> <input type="submit" value="提交"> </form> </body> </html>
2)Ajax
对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,一个是通过html提交csrf_token,另一个方式是通过cookie来提交到服务端。
方式一
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>csrf1</title> </head> <body> {% csrf_token %} /*必须要的,因为这是服务器产生的csrf字符串,并下发给客户端的*/ <a onclick="Do();">AJAX提交</a> <script src="/static/jQuery-3.3.1.js"></script> <script> function Do() { var user = $('#user').val(); var csrf1 = $('input[name="csrfmiddlewaretoken"]').val(); $.ajax({ url:"/csrf1.html", type:'POST', data:{'user':user,'csrfmiddlewaretoken':csrf1}, success:function (arg) { console.log(arg); } }); } </script> </body> </html>
方式二、要导入jquery.cookie.js文件,这个文件是用来处理cookie字符串的,用来分割,可以查document.cookie:"csrftoken=049rQhDWuAiYCEMHQx8r6pgVoqQyAQZpxY2BySmIqvrhinLaqjiRfGPP13eMeGd9"
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>csrf1</title> </head> <body> {% csrf_token %} <a onclick="Do();">AJAX提交</a> <script src="/static/jQuery-3.3.1.js"></script> <script> function Do() { var token = $.cookie('csrftoken'); var user = $('#user').val(); $.ajax({ url:"/csrf1.html", type:'POST', headers:{'X-CSRFToken':token}, /*要放在请头中提交*/ data:{'user':user}, success:function (arg) { console.log(arg); alert('提交成功') } }); } </script> </body> </html>
浙公网安备 33010602011771号