기본적으로 JWT양식을 작성할 때에는 탈취당했을 때를 대비하여(탈취를 안당하면 가장 좋지만) 보안상 문제가 되지 않는 수준까지의 정보만 담아야 한다.
(비밀번호 같은 것을 Payload에 담게 된다면 큰일이겠지...)
만료시간 : 15분
아래 각 부분마다 base64인코딩
1. 헤더(Header)
{
"typ": "JWT",
"alg": "HS256"
}
2. 정보(Payload)
{
"iss": "우리 도메인",
"iat": "현재 시각"
"exp": "현재 시각 + 15분",
"공개 클레임(public claim)": true,
"userId": "유저 id",
}
3개의 등록된 클레임(iss, iat, exp)
1개의 공개 클레임
1개의 비공개 클레임(userId)
3. 서명(Signature)
헤더, 정보를 각각 base64인코딩
>인코딩한 값을 secret key를 이용해서 헤더에서 정의한 HS256으로 해싱
>전체를 base64 인코딩
토큰 유효성 검사
exports.auth = (req, res, next) => {
try {
req.decoded = jwt.verify(req.headers.authorization, SECRET_KEY);
return next();
}
catch (error) {
// 유효시간이 초과된 경우
if (error.name === 'TokenExpiredError') {
return res.status(419).json({
code: 419,
message: '토큰이 만료되었습니다.'
});
}
// 토큰의 비밀키가 일치하지 않는 경우
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
code: 401,
message: '유효하지 않은 토큰입니다.'
});
}
}
}
토큰 인증
const { auth } = require('./authMiddleware');
const SECRET_KEY = 'MY-SECRET-KEY';
router.get('/payload', auth, (req, res) => {
const nickname = req.decoded.nickname;
const profile = req.decoded.profile;
return res.status(200).json({
code: 200,
message: '토큰은 정상입니다.',
data: {
nickname: nickname,
profile: profile
}
});
});