Cookie 未通过 Axios 发送

une*_*eer 6 django cookies vue.js axios nuxt.js

我有一个基于 Nuxt/vuejs 构建的表单。在 django 的后端,启用了 CSRF 保护,现在需要 Api 中的两件事调用X-CSRFToken作为标头和csrftoken作为 Cookie ,我通过 Postman 调用 Api 来测试 Api,这工作正常,但在 Vue 的情况下它没有通过 post 请求发送 Cookie 让我向您展示我的代码

axios 发布请求

const headers = {
    "X-CSRFToken": "some token",
    "Cookie": "csrftoken=some token",
}
await axios.post(`onboarding/first-name-last-name-email/`, {
    "first_name": "uneeb2",
    "last_name": "sad",
    "email": "asdsa@asd.colm"
}, {
    headers: headers
}, {
    withCredentials: true
})
Run Code Online (Sandbox Code Playgroud)

我也尝试过Fetch是否也有同样的问题

fetch(
  'https://staging.goqube.io/api/onboarding/first-name-last-name-email/',
  { credentials: 'include' ,method: "POST",headers:headers} // could also try ''
).then(res => {
  if (res.ok) return res.json()
  // not hit since no 401
})
Run Code Online (Sandbox Code Playgroud)

我还尝试在 axios 中设置默认值,它适用于 header key,但 cookie 仍然没有发送

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
Run Code Online (Sandbox Code Playgroud)

这里要提到的一件重要的事情是 CORS 是由服务器启用的,所以我没有为此做任何具体的事情。

我还尝试将 cookie 设置为本机

document.cookie = "csrftoken=some token; Path=/; Expires=Mon, 16 Feb 2023 08:02:50 GMT;"; 
Run Code Online (Sandbox Code Playgroud)

通过这个我可以看到浏览器上设置了 Cookie,但这仍然没有通过 post 请求发送 cookie

正如您所看到的,我也尝试过withCredentials: true这是常见的建议解决方案之一,但就我而言,这并不起作用。

关于服务器配置,Django服务器是一个独立的远程服务器,Nuxt应用程序也是如此。

我已经为此苦苦挣扎了很长一段时间,有人可以向我指出这可能是什么问题吗?

小智 5

我遇到了同样的问题,这就是我解决的方法

为了让 axios 发送 cookiewithCredentials应该是true,而withCredentials后端true必须发送一个Access-Control-Allow-Credentials标头,否则你会得到一个cors 缺少允许凭据错误,并且 cookie 将不会在浏览器中设置(现在的问题是 axios 可以'不要发送cookie,因为它们甚至没有在浏览器中设置)。

你说你已经CORS启用了,所以我假设你已经corsheaders在你的中INSTALLED_APPS,并且你已经将你的 vue 前端 url 添加到了CORS_ALLOWED_ORIGINS中的列表中settings.py。您还应该添加CORS_ALLOW_CREDENTIALS = Truesettings.py.

现在,在您的 vue 应用程序中设置 csrf cookie 和标头名称,如下所示,这样您就不需要手动获取 cookie 值并将其设置为标头X-CSRFToken,axios 会这样做。

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFToken"
Run Code Online (Sandbox Code Playgroud)

然后在发出请求时设置withCredentials为,或者您可以将其设置为默认值,如下所示true

axios.defaults.withCredentials = true;
Run Code Online (Sandbox Code Playgroud)

你可以参考这篇博文