返回

Django前后端分离项目CSRF Token undefined问题解决指南

javascript

在前后端分离项目中,Django 的 CSRF Token 问题确实让不少开发者头疼,特别是当你把代码迁移到新环境后,之前好好的代码突然就报 403 Forbidden 错误,CSRF Token 也变成了 undefined,这很可能和浏览器处理 Cookie 的方式有关。

我们先来简单回顾一下 Django 的 CSRF 保护机制。为了防止跨站请求伪造攻击,Django 使用 CSRF Token 来验证请求的合法性。简单来说,前端在发送 POST、PUT、DELETE 等请求时,需要把 CSRF Token 附带在请求头或请求体中。Django 后端会验证这个 Token 是否与服务器端存储的 Token 一致,如果不一样,就会拒绝请求。

你的代码中,前端使用 Cookies.get('csrftoken') 获取 CSRF Token。这说明你的前端框架 Vue 使用 Cookie 来存储 CSRF Token。 问题可能出现在以下几个方面:

  1. 浏览器 Cookie 设置 : 不同的浏览器,甚至同一浏览器的不同配置,对 Cookie 的处理方式都可能不一样。比如,有些浏览器可能会默认禁用第三方 Cookie,或者对 Cookie 的存储路径有限制。这些都可能导致前端无法正确读取 CSRF Token。
  2. 跨域问题 : 你的前端和后端运行在不同的端口上(前端 5173,后端 8000),这属于跨域访问。浏览器默认会阻止跨域请求携带 Cookie。虽然你的 Django 设置中已经配置了 CORS_ALLOWED_ORIGINSCORS_ALLOW_CREDENTIALS,但浏览器端的设置也需要检查一下。
  3. 网络环境 : 网络代理、防火墙这些东西也可能干扰 Cookie 的传递。

那么,怎么解决这个问题呢?我们可以试试以下几种方法:

1. 检查浏览器 Cookie 设置 :

  • 确保浏览器没有禁用第三方 Cookie。
  • 检查 Cookie 的存储路径是否正确。
  • 可以试试清除浏览器缓存和 Cookie,然后重新登录。

2. 确认跨域请求携带 Cookie :

  • 在前端发送请求时,设置 credentials: 'include',告诉浏览器发送 Cookie。
  • 可以打开浏览器开发者工具的网络请求,看看请求头中是否包含 Cookie 字段,以及 Cookie 字段中是否包含 csrftoken

3. 检查 Django 设置 :

  • 确保 CSRF_TRUSTED_ORIGINS 中包含前端的域名或 IP 地址。
  • 确保 CORS_ALLOWED_ORIGINS 中包含前端的域名或 IP 地址。
  • 确保 CORS_ALLOW_CREDENTIALS 设置为 True

4. 简化环境 :

  • 为了排除网络环境的影响,可以尝试在同一台电脑上运行前后端。
  • 还可以试试使用不同的浏览器,排除浏览器兼容性问题。

5. 使用其他方式获取 CSRF Token :

  • Django 提供了 csrf_token 模板标签,可以在 HTML 中渲染 CSRF Token。前端可以通过 JavaScript 获取这个 Token。
  • Django 还有一个 API 接口 /csrf/,可以通过 GET 请求获取 CSRF Token。

代码示例 :

前端 (Vue) :

// 使用 API 接口获取 CSRF Token
fetch('http://127.0.0.1:8000/csrf/', {
  credentials: 'include',
})
.then(response => response.json())
.then(data => {
  const csrfToken = data.csrfToken;
  // 将 csrfToken 存储到本地或直接使用
  localStorage.setItem('csrfToken', csrfToken);
  // ... 发送其他请求时,在请求头中添加 X-CSRFToken
});

后端 (Django) :

# settings.py
CORS_ALLOWED_ORIGINS = [
    'http://127.0.0.1:5173',
    'http://localhost:5173',
]
CORS_ALLOW_CREDENTIALS = True
CSRF_TRUSTED_ORIGINS = [
    'http://127.0.0.1:5173',
    'http://localhost:5173',
]

Django 的 CSRF 保护机制对 Web 应用的安全至关重要。在前后端分离项目中,我们需要仔细配置前后端,确保 CSRF Token 能够正确传递。通过排查浏览器 Cookie 设置、跨域请求、Django 设置等方面,一般都能解决 CSRF Token 无法读取的问题。

当然,实际操作中,可能还需要根据具体情况进行调整。如果问题还是解决不了,可以提供更详细的错误信息和代码片段,这样才能更好地理解问题,给出更精准的帮助。

常见问题及解答

1. 为什么我的浏览器禁用了第三方 Cookie?

有些浏览器为了保护用户隐私,会默认禁用第三方 Cookie。第三方 Cookie 指的是由非当前网站域名设置的 Cookie。在前后端分离项目中,前端和后端域名不同,CSRF Token 就可能被浏览器视为第三方 Cookie 而被禁用。

2. 如何启用第三方 Cookie?

不同的浏览器启用第三方 Cookie 的方法略有不同。一般可以在浏览器设置的隐私或安全选项中找到相关设置。

3. credentials: 'include' 有什么作用?

credentials: 'include' 是 Fetch API 的一个选项,用于告诉浏览器在跨域请求中包含 Cookie。

4. CSRF_TRUSTED_ORIGINSCORS_ALLOWED_ORIGINS 有什么区别?

CSRF_TRUSTED_ORIGINS 用于指定哪些域名可以发送 CSRF Token。CORS_ALLOWED_ORIGINS 用于指定哪些域名可以进行跨域请求。

5. /csrf/ API 接口有什么作用?

/csrf/ API 接口用于获取 CSRF Token。前端可以通过 GET 请求访问该接口,然后将获取到的 Token 存储到本地,并在后续请求中使用。

希望以上内容能帮到大家!