
``
/** refresh token 리프레쉬 토큰은 로그인 만료 기능을 수행 할 수 있게 만든다. 보안성이 많이 올라간다.
import express from 'express';
import jwt from 'jsonwebtoken';
import cookieParser from 'cookie-parser';
const app = express();
const PORT = 3019;
----비밀키 노출 방지를 위해 .env에 관리 할 것------
const ACCESS_TOKEN_SECRET_KEY = HangHae99;
const REFRESH_TOKEN_SECRET_KEY = Sparta;
app.use(express.json());
app.use(cookieParser());
const tokenStorages = {};
app.get('/', (req,res) => {
return res.status(200).send('Hello Token!');
});
-----------엑세스, 리프레시 토큰 발급-----------
app.post('/tokens, async (req,res) => {
const {id} = req.body; id값을 가져와서,
const accessToken = jwt.sign({id: id}, ACCESS_TOKEN_SECRET_KEY, {expiresIn: '10s'}); id, 비밀값, 파기날짜 순으로 넣는다.
const refreshToken = jwt.sign({id: id}, REFRESH_TOKEN_SECRET_KEY, {expiresIn: '7d'});
tokenStorages[refreshToken] = { 이곳에 tokenUserInfo 임시 저장
id: id,
ip: req.ip,
userAgent: req.headers['user-agent'],
}
res.cookie('accessToken', accessToken); 비밀화를 해서 토큰 발급
res.cookie('refreshToken', refreshToken);
return res.status(200).json({message: 'Token이 정상적으로 발급되었습니다.'})
});
엑세스 토큰 검증 API
app.get('/tokens/validate', (req, res) => {
const accessToken = req.cookies.accessToken; 클라이언트 쿠키값 가져와서
if (!accessToken) { 쿠키가 없으면?
return res
.status(400)
.json({ errorMessage: 'Access Token이 존재하지 않습니다.' });
}
const payload = validateToken(accessToken, ACCESS_TOKEN_SECRET_KEY); 맨 아래에 함수있다. 함수 끝나면 토큰 아니면 빈값
if (!payload) { 토큰이 이상하면 혹은 만료되면
return res
.status(401)
.json({ errorMessage: 'Access Token이 유효하지 않습니다.' });
}
const { id } = payload; 토큰값이 id로 들어감
return res.json({
message: ${id}의 Payload를 가진 Token이 성공적으로 인증되었습니다.,
});
});
// Token을 검증하고 Payload를 반환합니다.
function validateToken(token, secretKey) {
try {
const payload = jwt.verify(token, secretKey);
return payload;
} catch (error) {
return null;
}
}
리프레시 토큰 검증 API
app.post('/tokens/refresh', (req, res) => {
const refreshToken = req.cookies.refreshToken; 리프레시 쿠키를 가져온다.
if (!refreshToken) 쿠키가 없으면,
return res
.status(400)
.json({ errorMessage: 'Refresh Token이 존재하지 않습니다.' });
const payload = validateToken(refreshToken, REFRESH_TOKEN_SECRET_KEY); 위에랑 동일
if (!payload) {
return res
.status(401)
.json({ errorMessage: 'Refresh Token이 유효하지 않습니다.' });
}
const userInfo = tokenStorage[refreshToken]; 서버에서 유저 정보를 가져온다.
if (!userInfo) 정보가 없으면,
return res.status(419).json({
errorMessage: 'Refresh Token의 정보가 서버에 존재하지 않습니다.',
});
const newAccessToken = createAccessToken(userInfo.id); (실수로 만료기간 안 적을 수도 있으니 그냥 함수로 뺄 것)
res.cookie('accessToken', newAccessToken); 리프레시 토큰이 있으면 액세스 토큰을 새로 받을 수 있다~
return res.json({ message: 'Access Token을 새롭게 발급하였습니다.' });
});
// Token을 검증하고 Payload를 반환합니다.
function validateToken(token, secretKey) { 토큰이랑 시크릿 키값이 들어오면
try {
const payload = jwt.verify(token, secretKey); verify를 이용해 토큰과 비밀값이 유효하면 토큰 리턴, 아니면 에러
return payload;
} catch (error) {
return null;
}
}
**/