Django —— csrf 验证问题

亦凉 2022-05-31 04:43 285阅读 0赞

关于 csrf 的基本了解

百度百科:CSRF(Cross-site request forgery)跨站请求伪造,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。通过伪装来自受信任用户的请求来利用受信任的网站。

简单来说就是攻击者盗用你的身份,以你的名义来发送恶意请求。比如说用户通过账号密码访问了网站A,A网站将一些cookie信息保存在浏览器中实现用户状态行为跟踪。这时用户又打开了B网站,B网站返回了一些恶意代码,并请求访问A。这样浏览器就会携带cookie以用户的权限访问A网站并执行代码。而在服务器看来,这些都是正常的用户操作。

在Django 中对csrf 的防范

Django中自带了防止csrf攻击的功能,但对于初学者来说可能不知道如何使用,并给自己带来些意外的麻烦。

例如:一个正常的表单提交操作却总是报错。

Django 中GET请求不需要csrf认证,post请求需要正确的认证才能得到正确的返回结果。
我们先处理一下对表单提交的 csrf 验证问题:一般在POST表单中加入{% csrf_token %}

  1. <form method="POST" action="#">
  2. {% csrf_token %}
  3. <input name='password' value='用户密码'>
  4. </form>

加入了这句话后,再次提交post表单就不会出现问题了。
或者是另一个思路:禁用csrf
不过这样可能带来的危害你自己要想清楚了。
全局禁用:settings文件中找到关于csrf的中间件,直接注释。对于需要保护的视图加装饰器@csrf_protect。
针对性禁用:在表单提交的对应视图函数上加上一个装饰器 @csrf_exempt
关于csrf的装饰器官方文档:https://docs.djangoproject.com/en/2.2/ref/csrf/#module-django.views.decorators.csrf
对视图类使用装饰器:https://docs.djangoproject.com/en/2.2/topics/class-based-views/intro/#decorating-the-class

-————————————————————————————————-
{% csrf_token %} 实际上是一个模板语法,将项目的token值写入到前端页面的表单中,这个值在建django项目时就已经自动生成,可以在setting中看到。
-—————————————————————————————————-

下面再看一下Ajax调用时的处理方式

使用ajax与有开启csrf验证的视图进行交互时,需要确保ajax中能够获取到csrf token值
一 从当前html页面中获取token值(cookie也同时拥有token),如果是前后端分离,是没有这个的
二 如果从session 中获取 settings设置CSRF_USE_SESSIONS=True(token存储在session而不是cookie中)
三 如果从cookie 中获取 settings设置CSRF_COOKIE_HTTPONLY=False(默认)

Django提供了一个强制设置cookie的视图装饰器: ensure_csrf_cookie。

  1. function getCookie(name) {
  2. var cookieValue = null;
  3. if (document.cookie && document.cookie !== '') {
  4. var cookies = document.cookie.split(';');
  5. for (var i = 0; i < cookies.length; i++) {
  6. var cookie = cookies[i].trim();
  7. // Does this cookie string begin with the name we want?
  8. if (cookie.substring(0, name.length + 1) === (name + '=')) {
  9. cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
  10. break;
  11. }
  12. }
  13. }
  14. return cookieValue;
  15. }
  16. var csrftoken = getCookie('csrftoken');
  17. // 通过使用JavaScript Cookie库替换以上代码可以简化getCookie:
  18. // var csrftoken = Cookies.get('csrftoken');
从html中获取

如果csrf使用了session模式或者是禁止了cookie模式,需要从html中获取csrf token

  1. <script type="text/javascript">
  2. // using jQuery
  3. var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
  4. // 如果是使用django模版的页面
  5. // var csrftoken = '{% csrf_token %}'
  6. </script>
在data中添加token发送
  1. // 每个ajax中都需要传递csrfmiddlewaretoken
  2. $.ajax({
  3. url: ,url
  4. type: "POST",
  5. data: {
  6. "username": username,
  7. "password": password,
  8. // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data总
  9. "csrfmiddlewaretoken": csrftoken
  10. },
  11. success: function(data){
  12. console.log(data);
  13. }
  14. })
在请求头上添加token发送

这样写可以不必为每个ajax的data中添加csrf token

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

发表评论

表情:
评论列表 (有 0 条评论,285人围观)

还没有评论,来说两句吧...

相关阅读