我试图保护经过身份验证的用户的页面,但遇到一个错误,我的后端未收到 cookie 和授权标头。
在搜索错误时,我找到了解决该错误的方法,使用:
headers: {
Authorization: `Bearer ${TOKEN}`
}
但是当我在后端设置cookie时,我使用
"httpOnly: true"
来获得更好的安全性,因此我无法从客户端(前端)访问令牌。这就是为什么我在 cors 和 axios 中配置“credentials: true”,以便在每个请求中它们自动发送令牌
Cors 配置(后端):
const corsConfig = {
origin: [process.env.BASE_URL],
credentials: true,
allowedHeaders: ["Content-Type"],
}
Axios 配置(前端):
const api = axios.create({
withCredentials: true,
baseURL: BASE_URL
})
Cookie JWT Auth 中间件:
const cookieJwtAuth = async (req, res, next) => {
try {
console.log(req.headers);
const [, token] = req.headers.authorization.split(" ");
if (!token) {
return res.status(401).json({
statusCode: 401,
message: "Token not found",
});
}
const decodedToken = await jwt.verify(token, process.env.SECRET);
if (!decodedToken.username) {
return res.status(401).json({
statusCode: 401,
message: "Username not found in token",
});
}
req.user = decodedToken;
next();
} catch (err) {
res.clearCookie("auth");
return res.status(400).json({
statusCode: 400,
message: "Not authorized",
})
}
}
当通过前端的请求与通过 Insomnia 的请求不同时,我注意到 console.log 行中出现错误
注意: 在 Insomnia 上测试路线时,它可以正常工作
console.log(req.headers) - 前端:
{
host: 'localhost:666',
connection: 'keep-alive',
'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
accept: 'application/json, text/plain, */*',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
'sec-ch-ua-platform': '"Windows"',
origin: 'http://127.0.0.1:5500',
'sec-fetch-site': 'cross-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'http://127.0.0.1:5500/',
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6'
}
console.log(req.headers) - 失眠:
{
host: 'localhost:666',
cookie: 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkVSSUNaQVJETyIsImlkIjoiMyIsImlhdCI6MTcxNDcwMDUzNiwiZXhwIjoxNzE0NzAwNTk2fQ.yo_H_yvxIQC1cwphXoXiVnOKWPNTL74dDS26gLgA9oc; auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkVSSUNaQVJETyIsImlkIjoiMyIsImlhdCI6MTcxNDc4MDQ1MiwiZXhwIjoxNzE0ODY2ODUyfQ.mTRXYF6O7fJEGvw8NqebbMy0q1SwUYRtKe0AIhVpyeQ',
'user-agent': 'insomnia/9.1.0',
authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkVSSUNaQVJETyIsImlkIjoiMyIsImlhdCI6MTcxNDc4MDQ1MiwiZXhwIjoxNzE0ODY2ODUyfQ.mTRXYF6O7fJEGvw8NqebbMy0q1SwUYRtKe0AIhVpyeQ',
accept: '*/*'
}
我对 cors 和 axios 设置进行了一些更改,认为这是错误。我还尝试在Cors配置中添加AllowedHeaders“Authentication”
但我意识到错误仅出现在前端,因为如果像本例中那样未定义值,则无法使用 split 方法。
我仍然认为这只是一个小修改,但我仍然需要一点帮助。 如果您需要有关问题或代码任何部分的更多详细信息,请在评论中告诉我
经过多次尝试,我开始检查前端“检查”选项卡中的所有内容(我对此了解不多,并且开始深入研究)。因此,当我设置 cookie 时,会返回一个错误:
此 Set-Cookie 标头未指定“SameSite”属性,并且是 默认为“SameSite=Lax”,并被阻止,因为它来自 跨站点响应,这不是对顶级的响应 导航。 Set-Cookie 必须设置为“SameSite=None” 启用跨站点使用。
显然这种设置 cookie 的新方法已经解决了:
const token = jwt.sign({ username, id }, SECRET,{ expiresIn:'24h' })
res.cookie("auth", token, {
httpOnly: true,
secure: true,
sameSite: "None"
});