我正在学习 NodeJS,我正在尝试创建一个登录和注销端点,端点本身没有问题,因为请求返回它应该返回的内容,并在登录时正常设置 cookie,但问题是在注销端点中,因为它没有定义 cookie 并且未定义注销。
后端:
const bcrypt = require("bcrypt");
const users = {
users: require("../model/users.json"), //usually gets the data from an outside DB
setUsers: function (data) {
this.users = data;
},
};
const jwt = require("jsonwebtoken");
require("dotenv").config();
const fsPromises = require("fs").promises;
const path = require("path");
const login = async (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res
.status(400)
.json({ success: false, message: "username and password are required" });
}
const userFound = users.users.find((user) => user.username === username);
if (!userFound) {
return res.status(400).json({ success: false, message: "user not found" });
}
const isPasswordMatch = await bcrypt.compare(password, userFound.password);
if (!isPasswordMatch) {
return res
.status(401)
.json({ success: false, message: " password is invalid" });
}
const accessToken = jwt.sign(
{ username: username },
process.env.ACCESS_TOKEN_SECRET,
{
expiresIn: "1d",
}
);
const refreshToken = jwt.sign(
{ username },
process.env.REFRESH_TOKEN_SECRET,
{
expiresIn: "1w",
}
);
const otherUsers = users.users.filter(
(user) => user.userName != userFound.userName
);
const currentUser = { ...userFound, refreshToken };
users.setUsers([...otherUsers, currentUser]);
await fsPromises.writeFile(
path.join(__dirname, "../model", "users.json"),
JSON.stringify(users.users, null, 1),
"utf-8"
);
// Set the cookie after sending the response
res.cookie("jwt", refreshToken, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000, // 24 hours in milliseconds
sameSite: "None",
// secure: true, // Only set in production mode when serving over HTTPS
});
return res.status(200).json({ success: true, message: accessToken });
};
module.exports = { login };
退出:
const users = {
users: require("../model/users.json"), //usually gets the data from an outside DB
setUsers: function (data) {
this.users = data;
},
};
const fsPromises = require("fs").promises;
const path = require("path");
const logout = async (req, res) => {
const cookies = req.cookies;
console.log(cookies);
if (!cookies?.jwt) {
return res.sendStatus(204); //no content to send back but a successful request
}
const refreshToken = cookies.jwt;
//is refreshToken in DB
const UserFound = users.users.find(
(user) => user.refreshToken === refreshToken
);
if (!UserFound) {
res.clearCookie("jwt", {
httpOnly: true,
sameSite: "none",
//secure: true,
});
return res
.status(204)
.json({ success: true, message: "logged out successfully" });
}
const otherUsers = users.users.filter(
(user) => user.userName != UserFound.userName
);
const currentUser = { ...UserFound, refreshToken: "" };
users.setUsers([...otherUsers, currentUser]);
await fsPromises.writeFile(
path.join(__dirname, "../model", "users.json"),
JSON.stringify(users.users, null, 1),
"utf-8"
);
res.clearCookie("jwt", {
httpOnly: true,
sameSite: "None",
//secure: true,
}); //in production mode add extra setting called secure:true when modifying the cookie makes it only serve on https websites
return res
.status(204)
.json({ success: true, message: "logged out successfully" }); //no content to send back but a successful request
};
module.exports = { logout };
浏览器存储仅 http 的 cookie,并将其与所有请求一起发送到其中指定的域。您无法从 React 或任何其他框架访问此 cookie,浏览器将保护此数据免遭任何访问。
如您所见,这是您将其用于“刷新令牌”等敏感数据的主要原因