JSON WEB TOKEN
앞에서 인증을 위한 정보를 세션에 저장하였다면 이제는 따로 저장하지 않아도 전자 서명을 이용하여 확인할 수 있는 방법
이다.
Header : 3가지 정보를 암호화할 방식(alg), 토큰의 타입(type)
Payload : 전달되는 데이터
Verify Signature : Base64 방식으로 인코딩한 Header,payload 그리고 SECRET KEY를 더한 후 서명
header와 payload는 base64Url 인코딩 된 문자열이기 때문에 토큰을 가지고 있다면 누구나 header와 payload의 값을 위, 변조 할 수 있다. 하지만 Signature 부분이 존재해 서버에만 저장되어 있는 secret key으로 이것이 위, 변조 되었는지 확인할 수 있다.
클라이언트에서 로그인
서버는 로그인 된 유저 정보로 JWT을 생성 후 클라이언트에게 전달 (서버에서 따로 해당 JWT를 저장하지 않는다.)
setUserToken= (res, user) => {
// 유저 정보로 JWT을 생성
const token = jwt.sign(user, secret);
// 해당 JWT를 클라이언트에게 전달
res.cookie('token', token);
}
---
router.post('/', passport.authenticate('local'),
(req, res, next) => {
// 미들웨어를 사용하여 디비에서 사용자 확인 후 JWT를 생성
setUserToken(res, req.user);
res.redirect('/');
}
);
서버에서 JWT가 포함된 req를 받았을 때 JWT header의 alg에 적힌 알고리즘과 secret을 통해 signature를 복호화하여 signature 안에 들어있는 header, payload의 내용과 실제 header, payload의 내용이 일치여부를 판단하여 위, 변조되었는지 확인
// 모든 요청에 토큰이 있을 경우 로그인 된 상태로 처리하기 위한 미들웨어
app.use((req, res, next) => {
if (!req.cookies.token) {
next();
return;
}
return passport.authenticate('jwt')(req, res, next);
});
const JwtStrategy= require('passport-jwt').Strategy;
const cookieExtractor= (req) => {
const { token } = req.cookies;
return token;
}
const opts = {
secretOrKey: secret,
jwtFromRequest: cookieExtractor,
}
// passport-jwt 라이브러리에서 내부적으로 JWT의 서명을 확인하고 인증해준다.
module.exports= new JwtStrategy(opts, (user, done) => {
done(null, user);
});
---
passport.use(jwt)