插件窝 干货文章 Django CSRF保护机制:两个Token如何协同工作并有效防止跨站攻击?

Django CSRF保护机制:两个Token如何协同工作并有效防止跨站攻击?

CSRF Token Cookie 表单 389    来源:    2025-03-13

Django的CSRF(Cross-Site Request Forgery)保护机制通过使用两个Token来协同工作,有效防止跨站攻击。这两个Token分别是:

  1. CSRF Token:这是一个随机生成的字符串,通常嵌入在HTML表单中作为一个隐藏字段(<input type="hidden" name="csrfmiddlewaretoken" value="...">)。这个Token在每次表单提交时都会被发送到服务器。

  2. CSRF Cookie:这是一个存储在用户浏览器中的Cookie,通常命名为csrftoken。这个Cookie的值与表单中的CSRF Token相匹配。

协同工作流程

  1. 生成Token

    • 当用户访问一个包含表单的页面时,Django会生成一个CSRF Token,并将其嵌入到表单中作为一个隐藏字段。
    • 同时,Django会生成一个CSRF Cookie,并将其发送到用户的浏览器。
  2. 提交表单

    • 当用户提交表单时,浏览器会自动将表单中的CSRF Token和CSRF Cookie一起发送到服务器。
  3. 验证Token

    • 服务器接收到请求后,会从请求中提取出CSRF Token和CSRF Cookie。
    • 服务器会检查这两个Token是否匹配。如果匹配,请求被认为是合法的,继续处理;如果不匹配,请求会被拒绝,并返回403 Forbidden错误。

防止跨站攻击的原理

  1. 同源策略

    • 浏览器遵循同源策略,即只有来自同一站点的请求才能访问和操作该站点的资源。CSRF攻击通常发生在攻击者诱导用户访问恶意网站,并在用户不知情的情况下向目标站点发送请求。
  2. Token验证

    • 由于CSRF Token是随机生成的,并且与CSRF Cookie匹配,攻击者无法伪造有效的Token。即使攻击者能够诱导用户发送请求,但由于缺少有效的CSRF Token,请求会被服务器拒绝。
  3. Cookie的SameSite属性

    • Django默认设置CSRF Cookie的SameSite属性为Lax,这意味着浏览器只会在同站点请求或顶级导航(如点击链接)时发送Cookie。这进一步减少了CSRF攻击的风险。

配置与使用

  1. 启用CSRF保护

    • Django默认启用了CSRF保护,可以通过中间件django.middleware.csrf.CsrfViewMiddleware来实现。
  2. 在表单中使用CSRF Token

    • 在Django模板中,可以使用{% csrf_token %}标签来生成CSRF Token并嵌入到表单中。
    <form method="post">
       {% csrf_token %}
       <!-- 其他表单字段 -->
       <input type="submit" value="提交">
    </form>
    
  3. 在AJAX请求中使用CSRF Token

    • 对于AJAX请求,可以通过JavaScript从Cookie中获取CSRF Token,并将其添加到请求头中。
    function getCookie(name) {
       let cookieValue = null;
       if (document.cookie && document.cookie !== '') {
           const cookies = document.cookie.split(';');
           for (let i = 0; i < cookies.length; i++) {
               const cookie = cookies[i].trim();
               if (cookie.substring(0, name.length + 1) === (name + '=')) {
                   cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                   break;
               }
           }
       }
       return cookieValue;
    }
    
    const csrftoken = getCookie('csrftoken');
    
    fetch('/your-endpoint/', {
       method: 'POST',
       headers: {
           'X-CSRFToken': csrftoken,
           'Content-Type': 'application/json'
       },
       body: JSON.stringify({ key: 'value' })
    });
    

总结

Django的CSRF保护机制通过生成和验证两个Token(CSRF Token和CSRF Cookie)来确保请求的合法性。这种机制有效防止了跨站请求伪造攻击,保护了用户的数据安全。通过合理配置和使用,开发者可以轻松地在Django应用中实现CSRF保护。