即使 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,参见:
- front-end http 服务(React 应用程序)在
http://172.16.2.19:3000
运行
- back-end http 服务 (expressjs) 运行
http://172.16.2.19:3001
- 我从 front-end 发送的 axios 请求请求:
http://172.16.2.19:3001
那么问题是什么?
没有在浏览器中创建 cookie 的问题阻止了我继续设计 front-end 应用程序,因为如果我想从我的 API 请求任何东西,我必须经过身份验证,我在 API 上创建的所有路由都受到保护,因此如果我想从 API 请求任何内容,我将必须随请求一起发送我的 jwt 令牌。
编辑**:
这是成功登录后 /auth/login 端点的响应:
- 我使用的是brave浏览器,最新版本。
- 我在 firefox 上试过,它有相同的行为。
我会通过将 {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 策略。
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,参见:
- front-end http 服务(React 应用程序)在
http://172.16.2.19:3000
运行
- back-end http 服务 (expressjs) 运行
http://172.16.2.19:3001
- 我从 front-end 发送的 axios 请求请求:
http://172.16.2.19:3001
那么问题是什么?
没有在浏览器中创建 cookie 的问题阻止了我继续设计 front-end 应用程序,因为如果我想从我的 API 请求任何东西,我必须经过身份验证,我在 API 上创建的所有路由都受到保护,因此如果我想从 API 请求任何内容,我将必须随请求一起发送我的 jwt 令牌。
编辑**:
这是成功登录后 /auth/login 端点的响应:
- 我使用的是brave浏览器,最新版本。
- 我在 firefox 上试过,它有相同的行为。
我会通过将 {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 策略。