세션 기반 인증 방식과 토큰 기반 인증(JWT)
세션 기반 인증 방식
옛날에 토큰 기반 인증이 없었을 때 서버 세션을 사용해 인증을 했다.
- 클라이언트가 로그인
- 성공하면 서버가 유저 세션을 만들고 메모리나 데이터베이스에 저장한다.
- 서버가 클라이언트에게 세션 ID를 보낸다.
- 클라이언트의 브라우저에 세션의 ID만 쿠키에 저장하게 한다.
세션 데이터가 서버의 메모리에 저장되므로, 확장 시 모든 서버가 접근할 수 있도록 별도의 중앙 세션 관리 시스템이 필요하다.
단점
- 중앙 세션 관리 시스템이 없으면, 시스템 확장에 어려움이 생긴다.
- 중앙 세션 관리 시스템이 장애가 일어나면, 시스템 전체가 문제가 생긴다.
- 만약 메모리에 세션 정보가 들어있다면, 메모리가 많이 사용될 수 있다.
규모 확장이 필요없는 소규모 프로그램 작성에서는 세션 기반 인증 방식을 사용해도 상관 없을 것이다.
JWT
JWT(Json Web Token)은 토큰 기반 인증 방식으로, 클라이언트의 세션 상태를 저장하는 게 아니라 필요한 정보를 토큰 body에 저장해 클라이언트가 가지고 있고 그것을 증명서처럼 사용한다.
기본 구성
xxxxx.yyyyy.zzzzz
3가지로 나눠진다.
- Header (
xxxxx
)— JWT인 토큰의 유형이나 HMAC SHA256 또는 RSA와 같이 사용되는 해시 알고리즘이 무엇으로 사용했는지 등 정보가 담긴다. Base64Url로 인코딩되어있다. - Payload (
yyyyy
)— 클라이언트에 대한 정보나, meta Data같은 내용이 들어있고, Base64Url로 인코딩되어있다. - Signature (
zzzzz
)— header에서 지정한 알고리즘과 secret 키, 서명으로 payload와 header를 담는다.
payload 내용
JWT는 내용을 해독해 볼 수 있으므로 중요한 데이터를 포함해선 안된다.
https://jwt.io/ 이곳에서 jwt를 해독할 수 있다.
JWT 보안 위험
JWT는 자체 내에 정보를 가지고 있기 때문에 클라이언트가 해독해 정보를 볼 수 있다. 하지만 받는 자가 secret 키를 알고 있어야만 수정이 가능하다.
- 작동 원리
- A가 B에게 JWT를 보내려한다.
- A, B 둘다 암호화한 secret 키를 알고 있다.
- C는 secret 키를 알지 못하지만 A, B 사이의 JWT를 몰래 변경하려한다.
- A는 이를 방지하기 위해 signature 부분에 (payload+secret key)를 특정 알고리즘으로 해시화해 추가했다.
- C가 이 JWT를 변경하려해도 secret key를 몰라 멋대로 변경할 수 없다.
- B는 C가 변경한 JWT를 받으면 서명이 다르기 때문에 받지 않는다.
수명
JWT의 수명을 짧게 하고 정기적으로 재발급을 요구하면 원치 않는 클라이언트를 빨리 막을 수 있다.
기본 인증 과정
간단한 JWT 인증 처리 과정이다.
- 클라이언트가 로그인을 하면, 서버로부터 access 토큰을 부여받는다.
- 이후 클라이언트가 모든 api 요청을 할 때 access 토큰을 포함시킨다.
- 서버는 access 토큰을 해독해 확인하고 검증되면 해당 api 기능을 수행한다.
- 기한이 만료되었으면 access 토큰을 지워주고 재로그인을 하게 한다.
문제점
- 클라이언트가 계속 시스템을 이용하다가 access 토큰 기한이 만료된다면 사용중에 갑자기 로그인을 하라고 할 것이다.
- 수명이 짧다면 만료될때마다 로그인 해주어야 한다.
- 수명이 길면 해커에게 해독되어 사용될 가능성이 높아진다.
Refresh Token
access 토큰이 만료되었을 때, Refresh 토큰으로 서벙새로운 access 토큰을 발급받을 수 있다.
필요성
- 서버 데이터베이스에 Refresh Token이 저장되어 있을때 클라이언트가 블랙리스트에 포함되어 있다면, access 토큰을 발급해주는 것을 막을 수 있다.
- Refresh Token으로 access 토큰이 만료되면 알아서 갱신한다.
토큰 처리 flow
웹과 모바일에서의 JWT 저장
React-Native로 개발한 모바일 앱에서는 KeyChain이나 KeyStore에서 암호화되게 JWT를 저장할 수 있는 라이브러리가 있다.
하지만 웹에서는 2가지의 선택이 있다.
- Cookies
- local/session storage.
local/session storage
동일한 도메인의 JavaScript를 통해 접근할 수 있으므로 XSS(크로스 사이트 스크립팅)공격에 취약하다.
Cookies
쿠키는 http-only
플래그를 사용해 암호화된 쿠키가 https로만 통신하도록 설정해 XSS의 문제를 완화시킬 수 있다.
하지만 CSRF
공격의 위험이 있다.
CSRF
는 최근에 인증된 사용자가 웹 프로그램에서 원치 않는 행위를 하도록 한다.
CSURF 같은 라이브러리를 사용하면 예방할 수 있다.
그래서 보안을 위해 보통 Cookie 사용을 권장한다.
참조