본문 바로가기
기타

[개념] JWT (JSON Web Token)

by oyeahhh 2021. 1. 2.

JWT (JSON Web Token)

데이터가 JSON으로 이루어져 있는 토큰을 의미
두 개체가 서로 안전하게 정보를 주고받을 수 있도록 웹 표준으로 정의된 기술

세션 기반 인증과 토큰 기반 인증의 차이

세션 기반 인증 시스템

  • 서버가 사용자가 로그인 중임을 기억하고 있다는 뜻

세션 기반 인증 시스템 흐름

  1. 사용자: 로그인
  2. 서버: 세션 저장소에 정보 조회 및 저장
    • 세션 저장소는 주로 메모리, 디스크, 데이터베이스 등을 사용한다
  3. 서버: 세션 id 발급, 사용자에게 전달
    • 발급된 세션 id는 주로 브라우저의 쿠키에 저장한다.
  4. 사용자: 세션 id와 함께 요청
  5. 서버: 세션 조회
  6. 서버: 응답

단점

서버를 확장하기가 번거로워질 수 있다.
서버 인스턴스가 여러 개라면 모든 서버끼리 같은 세션을 공유해야 하므로 세션 전용 데이터베이스를
따로 만들어야 할 뿐 아니라 신경 쓸 게 많다.

토큰 기반 인증 시스템

토큰: 로그인 이후 서버가 만들어 주는 문자열
토큰에는 사용자의 로그인 정보, 해당 정보가 서버에서 발급되었음을 증명하는 서명이 들어있다.
서명 데이터는 해싱 알고리즘을 통해서 만들어 진다 (주로 HMAC SHA256, RSA SHA256 알고리즘 사용)
토큰은 서명이 있기 때문에 무결성이 보장된다.
무결성: 정보가 변경되거나 위조되지 않았음을 의미하는 성질

토큰 기반 인증 시스템 흐름

  1. 사용자: 로그인
  2. 서버: 토큰 발급, 사용자에게 전달
  3. 사용자: 토큰과 함께 요청
  4. 서버: 토큰 유효성 검사
  5. 서버: 응답

장점

로그인 정보를 기억하기 위해 사용하는 리소스가 적다
로그인 상태를 사용자가 가지고 있으므로 서버의 확장성이 높다

JWT 비밀키

JWT 토큰을 발급할 때 비밀키가 필요하다.
비밀키는 문자열로 아무거나 입력할 수 있다.
하지만 절대 외부에 공개되서는 안된다.
비밀키가 공개되면 누구든지 마음대로 JWT 토큰을 발급할 수 있기 때문에
비밀키 생성 후 .env 파일에서 관리

$ openssl rand -hex 64

JWT 토큰 생성

jsonwebtoken 모듈 사용

import jwt from 'jsonwebtoken';

const token = jwt.sign(
  { _id: 'id', username: 'username' }, // 넣고 싶은 데이터
  process.env.JWT_SECRET,// jwt 비밀키
  { expiresIn: '7d' } // 유효 기간, 7일 동안 유효
)

JWT 사용 방법

브라우저의 localStorage, sessionStorage에 담아서 사용

  • 사용하기 편리하고 구현이 쉽다
  • 하지만 악성 스크립트 공격에 취약하다. 쉽게 토큰을 탈취할 수 있다. (XSS(Cross Site Scripting)

브라우저의 쿠키에 담아서 사용

  • 쿠키에서도 XSS 공격이 있을 수 있지만 httpOnly 속성을 활성화해서 자바스크립트를 통해 쿠키를 조회할 수 없도록 할 수 있다.
  • XSS 공격 외에 CSRF (Cross Site Request Forgery)라는 공격에 취약할 수 있다.
    • 토큰을 쿠키에 담으면 사용자가 서버로 요청할 때마다 무조건 토큰이 함께 전달되는 점을 이용
    • 사용자가 원하지 않는 API 요청을 하게 만든다.
    • CSRF 토큰 사용 및 Referer 검증을 통해 막을 수 있다.

댓글