refactor: refresh token with session cookies (auth function)

This commit is contained in:
elangptra 2024-10-03 11:09:35 +07:00
parent 53f2934a24
commit 95bbdf65b8
2 changed files with 57 additions and 29 deletions

View File

@ -1,4 +1,5 @@
APP_PORT = 3001 APP_PORT = 3001
NODE_ENV = development
DB_HOST = localhost DB_HOST = localhost
DB_USER = root DB_USER = root
@ -6,6 +7,7 @@ DB_PASSWORD =
DB_NAME = adaptive_learning DB_NAME = adaptive_learning
ACCESS_TOKEN_SECRET = ACCESS_TOKEN_SECRET =
REFRESH_TOKEN_SECRET =
RESET_PASSWORD_SECRET = RESET_PASSWORD_SECRET =
EMAIL_USER = EMAIL_USER =

View File

@ -269,6 +269,12 @@ export const loginUser = async (req, res) => {
{ where: { ID: user.ID } } { where: { ID: user.ID } }
); );
res.cookie("refreshToken", refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Strict",
});
const userResponse = { const userResponse = {
ID: user.ID, ID: user.ID,
NAME_USERS: user.NAME_USERS, NAME_USERS: user.NAME_USERS,
@ -286,24 +292,25 @@ export const loginUser = async (req, res) => {
}; };
export const refreshToken = async (req, res) => { export const refreshToken = async (req, res) => {
const { REFRESH_TOKEN } = req.body; const refreshToken = req.cookies?.refreshToken || req.body.REFRESH_TOKEN;
if (!REFRESH_TOKEN) { if (!refreshToken) {
return response(400, null, "Refresh token is required!", res); return response(400, null, "Refresh token is required!", res);
} }
try { try {
const user = await models.User.findOne({ where: { REFRESH_TOKEN } }); const user = await models.User.findOne({
where: { REFRESH_TOKEN: refreshToken },
});
if (!user) { if (!user) {
return response(403, null, "Invalid refresh token!", res); return response(403, null, "Invalid refresh token!", res);
} }
jwt.verify( let decoded;
REFRESH_TOKEN, try {
process.env.REFRESH_TOKEN_SECRET, decoded = jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET);
(err, decoded) => { } catch (err) {
if (err) {
if (err.name === "TokenExpiredError") { if (err.name === "TokenExpiredError") {
return response( return response(
401, 401,
@ -315,20 +322,39 @@ export const refreshToken = async (req, res) => {
return response(403, null, "Invalid refresh token!", res); return response(403, null, "Invalid refresh token!", res);
} }
if (decoded.ID !== user.ID) {
return response(403, null, "Invalid refresh token data!", res);
}
const newAccessToken = jwt.sign( const newAccessToken = jwt.sign(
{ ID: user.ID, ROLE: user.ROLE }, { ID: user.ID, ROLE: user.ROLE },
process.env.ACCESS_TOKEN_SECRET, process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: "3h" } { expiresIn: "3h" }
); );
const newRefreshToken = jwt.sign(
{ ID: user.ID, ROLE: user.ROLE },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: "7d" }
);
await models.User.update(
{ REFRESH_TOKEN: newRefreshToken },
{ where: { ID: user.ID } }
);
res.cookie("refreshToken", newRefreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Strict",
});
response( response(
200, 200,
{ TOKEN: `Bearer ${newAccessToken}` }, { TOKEN: `Bearer ${newAccessToken}`, REFRESH_TOKEN: newRefreshToken },
"Token refreshed successfully", "Token refreshed successfully",
res res
); );
}
);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);