Backend/Node.js

Node.js - JWT 기본

yxemsy 2022. 3. 7. 22:27

1) JWT

JSON Web Token의 약자로 flask 포스팅에도 잠깐 다루긴 했지만
인증을 위한 정보를 특별한 저장소를 이용하지 않고, 전자 서명을 이용하여 확인하는 방법이다.

 

- JWT의 구성

header - 토큰의 타입, 데이터 서명 방식
payload - 전달되는 데이터
signature - 헤더와 페이로드의 전자서명
  • JWT는 Web Token, 데이터를 웹에서 사용하기 위한 스펙이므로 웹에서 문제없이 사용할 수 있는 문자열로만 구성된 base64 인코딩을 사용

(JWT의 생김새는 이 포스팅에서 확인 가능)

 

  • 서버는 JWT를 생성할 때, 비공개키를 이용하여 서명한다. payload를 조작할 경우 서명이 일치하지 않기 때문에 인증에 실패한다.

 

- JWT 작동 방식

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

 

- JWT 사용 이유

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

 


 

2) JWT + Cookie 사용하기

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

 

- Session VS Cookie

 1) Session: 클라이언트 정보를 서버 측 저장소에 저장하고 사용

 2) Cookie: 클라이언트 정보를 클라이언트 (브라우저)에 저장하고 사용

 

 

- JWT 로그인 구현하기

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

 

 

- 로그인 로직에 JWT 토큰 생성 및 쿠키 전달

setUserToken = (res, user) => {
    const token = jwt.sign(user, secret)
    // res.cookie 함수 사용하여 token을 클라이언트에 쿠키로 전달
    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 JwtStratgy(opts, (user, done) => {
     done(null, user)
 })
 
 ---
 
 passport.use(jwt)
}

 

- JWT 미들웨어 추가

JWT 토큰은 기본적으로 모든 요청에 포함된다.

app.use((req, res, next) => {
    if (!req.cookies.token) {
        next()
        return
    }
    
    return passport.authenticate('jwt')(req, res, next)
    })

요청에 토큰이 있는 경우 로그인된 상태로 처리하기 위해

모든 요청에 공통적으로 적용할 수 있는 미들웨어로 JWT 로그인을 추가한다.

 

 

- 로그아웃

로그아웃은 간단하게 클라이언트 쿠키를 삭제하여 처리 가능하다.

res.cookie('token', null, {
    maxAge: 0,
})

token 값을 null로 전달하는 것과 함께, cookie의 만료 시간을 0으로 설정하여

클라이언트가 쿠키를 바로 만료시키도록 전달한다.

 

Nodemailer + Gmail 사용하기에 대한 구체적인 포스팅 보기

 

 

참고: 엘리스 AI트랙