JWT

Jong-uk·2023년 4월 15일
0

엘리스 온라인 학습

목록 보기
28/39

JWT?

  • JSON Web Token
  • 인증을 위한 정보를 특별한 저장소를 이용하지 않고, 전자 서명을 이용하여 확인하는 방법

구성

header - 토큰의 타입 (jwt), 데이터 서명 방식
payload - 전달되는 데이터
signature - 헤더와 페이로드의 전자서명

  • JWT 는 Web Token, 데이터를 웹에서 사용하기 위한 스펙이므로 웹에서 문제없이 사용할 수 있는 문자열로만 구성된 base64 인코딩을 사용

보안

  • JWT의 payload는 단순히 정보를 base64 encode → decode 시 정보 노출됨 → 민감한 정보는 제외하고 토큰 생성 필수
  • 서버는 JWT를 생성할 때, 비공개키를 이용하여 서명을 함
  • payload를 조작할 경우 서명이 일치하지 않기 때문에 인증 실패

작동 방식

  1. 사용자 로그인
  2. 서버는 로그인된 유저 정보를 JWT로 생성하여 클라이언트에 전달
  3. 클라이언트는 전달받은 JWT를 이용하여 인증이 필요한 요청에 사용

왜 사용?

  • session은 기본적으로 웹 브라우저의 통신 스펙
  • 모바일 앱 등, 웹 브라우저가 아닌 어플리케이션의 경우 이를 활용하기 부적합함
  • JWT를 사용하면 어느 클라이언트에서나 동일한 방식의 사용자 인증을 구현 가능

사용 방법

  • jwt.io 에서 실습 가능!!

JWT + Cookie

  • 웹 서비스에서 사용하는 정보를 클라이언트에 저장하고, HTTP 요청 시 이를 함께 전송하여, 클라이언트 정보를 서버에 전달하는 기술

세션이랑 뭐가 다름?

  • Session
    • 클라이언트 정보를 서버 측 저장소에 저장하고 사용
  • Cookie
    • 클라이언트 정보를 클라이언트 (브라우저)에 저장하고 사용

로직 차이

  • Session을 사용한 유저 로그인의 경우
    • Cookie에 Session ID 저장 → Session Store에서 유저 정보 가져오기
  • JWT를 쿠키에 저장하는 경우
    • JWT로 요청 → 서명 확인 후 유저 정보 사용
  • 데이터베이스 접근이 줄어서 효율적인 인증 구현 가능

사용 방법

  1. 기존 세션으로 구현된 로그인을 비활성화
  2. 로그인 로직에서 JWT 생성 후 쿠키로 전달
  3. passport-jwt 패키지로 JWT 로그인 미들웨어 작성 및 사용

로그인 로직에서 JWT 토큰 생성

  • res.cookie 함수 사용하여 token을 클라이언트에 쿠키로 전달
setUserToken = (res, user) => {
 const token = jwt.sign(user, secret);
 res.cookie('token', token);
}
---
router.post('/', passport.authenticate('local'),
 (req, res, next) => {
   setUserToken(res, req.user);
  res.redirect('/');
});

passport-jwt 사용하기

  • passport-jwt 패키지를 이용해 요청된 JWT 토큰의 서명을 확인하고 인증하는 기능을 구현
const JwtStrategy = require('passport-jwt').Strategy;
const cookieExtractor = (req) => {
 const { token } = req.cookies;
return token;
};
const opts = {
 secretOrKey: secret,
jwtFromRequest: cookieExtractor, }
module.exports = new JwtStrategy(opts, (user, done) => {
 done(null, user);
});
---
passport.use(jwt);

JWT 미들웨어

  • JWT 토큰은 기본적으로 모든 요청에 포함
  • 요청에 토큰이 있는 경우 로그인된 상태로 처리하기 위해 모든 요청에 공통적으로 적용할 수 있는 미들웨어로 JWT 로그인을 추가
app.use((req, res, next) => {
 if (!req.cookies.token) {
next();
return; }
return passport.authenticate('jwt')(req,
res, next);
});

로그아웃

  • 로그아웃은 간단하게 클라이언트 쿠키를 삭제하여 처리 가능
  • token 값을 null로 전달하는 것과 함께, cookie의 만료 시간을 0으로 설정하여 클라이언트가 쿠키를 바로 만료시키도록 전달
res.cookie('token', null, {
 maxAge: 0,
});
profile
안녕하세요! 만나서 반갑습니다.

0개의 댓글