即使 set-cookie header 存在,Axios 也不会创建 cookie?

Axios doesn't create a cookie even though set-cookie header is there?

Front-End: [Axios]

  const formSubmit = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const email = formData.get('email')
    const password = formData.get('password')
    try {
      const res = await axios.post('http://172.16.2.19:3001/api/v1/auth/login', {
        email,
        password,
      })
      console.log(res.data) // its okay, I can login if email & password are correct.
    } catch (error) {
      console.log(error)
    }
  }

Back-End [Nodejs ExpressJs]:

里面 App.js:

const cors = require('cors')
app.use(cors({ credentials: true }))

内部 Login.js(/auth/login 端点):

// ... code, then... if email & password are correct:
// 3600000ms = 1hour
res.cookie('jwt', token, { httpOnly: true, expires: new Date(Date.now() + 3600000 })
res.status(200).json({
    status: 'success'
    token,
    data: userDoc,
})

然后,当我在浏览器中登录时:

我可以登录成功,但是不会创建cookie,参见:

那么问题是什么?

没有在浏览器中创建 cookie 的问题阻止了我继续设计 front-end 应用程序,因为如果我想从我的 API 请求任何东西,我必须经过身份验证,我在 API 上创建的所有路由都受到保护,因此如果我想从 API 请求任何内容,我将必须随请求一起发送我的 jwt 令牌。

编辑**:

这是成功登录后 /auth/login 端点的响应:

我会通过将 {withCredentials: true} 作为第三个参数传递给 axios 方法来进行检查,以允许浏览器通过请求设置 cookie。

我认为使用后端保存 cookie 是不正确的,因为 cookie 是独立于数据库的浏览器功能。不过我可能是错的。当post成功后,res会return一个token。您将此令牌保存在浏览器的本地存储中。

const formSubmit = async (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const email = formData.get('email')
const password = formData.get('password')
try {
  const res = await axios.post('http://172.16.2.19:3001/api/v1/auth/login', {
    email,
    password,
  })
  //browsers local storage
  
  localStorage.setItem('access_token',res.data.access);
  localStorage.setItem('refresh_token',res.data.refresh);
  console.log(res.data) // its okay, I can login if email & password are correct.
}

然后您必须创建授权header

headers:{
        Authorization: localStorage.getItem('access_token') 
            ? 'JWT '+localStorage.getItem('access_token')
            : null

    }

GUYS GUYS GUYS 我找到了!!!!经过 3 小时的研究,让我节省您的时间:

对于遇到同样问题的任何人,您所要做的就是

更改您的后端代码:

const cors = require('cors')
app.use(cors({ credentials: true }))

app.use(cors({ credentials: true, origin: true }))

并确保您在 front-end 上对每个请求(登录 POST 方法和所有其他需要身份验证的请求)使用 withCredentials: true

为什么?

origin 属性 设置为 true 将反映请求来源,如果您想指定特定域,来源 属性 可以是字符串,例如:http://localhost:3000。但如果您有多个客户端,将此设置为 true 是一个明智的选择。

对于那些想知道移动设备的人来说,在为具有一个特定域的原始字段指定字符串的情况下。 cors 的这个问题只发生在浏览器中,任何其他客户端都不会使用该 CORS 策略。