我在Vercel(前端)和Heroku(后端)托管的MERN应用程序中遇到cookie问题。
在localhost中一切正常,但在部署时,我在存储cookie时遇到了问题。Set-Cookie随登录请求一起发送,请求本身看起来正常。我没有收到任何错误。
登录后,经过验证的路由返回我所期望的每个用户,所以cookie似乎是可以访问的后端,即使cookie没有存储在前端的存储器下,我认为这是一个安全问题。这是 * 不是 * 在Safari的情况下,在Safari的cookie在登录后消失,所以用户再次注销。
唯一不起作用的方法是注销。在注销时我清除了令牌cookie,但它试图删除一些 * 技术上 * 不存在的东西,仍然没有错误。更新:清除cookie有效!我没有在注销时发送任何数据,因此前端认为它没有响应,添加.send({ message: 'Sign Out Successful' })
解决了这个问题。但是,在前端存储中仍然看不到cookie。
对于CORS设置,我将origin设置为前端url,将credentials设置为true。而在前端,我对每个请求都设置了withCredentials: true
。
部署时,Cookie使用sameSite: none
和secure: true
。
以下是登录和注销路径,但您可以在GitHub上找到完整的后端代码here和前端代码here。
在后端登录路由
import type Route from '../../types/Route'
import jwt from 'jsonwebtoken'
import env from '../../env/env'
import bcrypt from 'bcryptjs'
import User from '../../models/User'
import validateSignIn from '../../utils/validation/signIn'
const route: Route = {
method: 'post',
execute: async (req, res) => {
const { username, password } = req.body.user
try {
const { errors, valid } = validateSignIn(username, password)
if (!valid) return res.status(401).send({ errors })
const user = await User.findOne({ username })
if (!user) return res.status(404).send({ errors: { username: 'User not found' }})
const correctPassword = await bcrypt.compare(password, user.password)
if (!correctPassword) return res.status(401).send({ errors: { password: 'Wrong password' } })
const token = jwt.sign({ userId: user._id }, env.SECRET, { expiresIn: "1hr" })
return res.status(200).cookie('token', token, {
expires: new Date(Date.now() + 604800000),
secure: env.ENVIRONMENT === 'LIVE',
sameSite: env.ENVIRONMENT === 'LIVE' ? 'none' : 'lax',
httpOnly: true
}).send(user)
} catch (error) {
console.log('@sign/in', error)
return res.sendStatus(500)
}
}
}
export default route
在后端 checkout 路由:
import type Route from '../../types/Route'
import authorization from '../../middlewares/http'
import env from '../../env/env'
// TODO: Fix Sign Out
const route: Route = {
method: 'get',
authorization,
execute: async (req, res) => {
try {
return res.clearCookie('token').sendStatus(200)
} catch (error) {
console.log('@sign/out', error)
return res.status(500)
}
}
}
export default route
2条答案
按热度按时间nbysray51#
.clearCookie()文件会指出
Web浏览器和其他兼容的客户端只有在给定的选项与res.cookie()的给定选项相同(不包括expires和maxAge)时才会清除cookie。
所以,试着让你的清除操作和你的集合操作相匹配,就像这样。
mccptt672#
我也有这个问题,我在vercel托管后端,在netlfy托管前端,当我试图注册cookie时,它没有显示在后端的响应中。