🌟 JWT (Json Web Token)

JWT는 Json 객체에 인증에 필요한 정보들을 담고 비밀키로 서명한 토큰이고, 인터넷 표준 인증 방식이다. 인증 & 인가에 사용되는 공식적인 방식이다.
🌟 JWT 구조
xxxxx.yyyyy.zzzzz
🌟 Header
{
"alg": "HS256",
"typ": "JWT"
}
xxxxx에 해당하는 부분이다. alg와 typ으로 이루어져있다.
- alg : Signautre에서 사용하는 알고리즘
- typ : 토큰 타입
대표적으로 alg엔 RS256(공개키/개인키), HS256(비밀키)가 있다. token type은 JWT이므로 JWT를 쓴다.
🌟 Payload
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
사용자 정보의 조각인 클레임(Claim)을 포함한다.
- sub : 토큰 제목
- aud : 토큰 대상자
- iat: 토큰 발급 시각 (issud at)
- exp: 토큰 만료 시각(expired)
🌟 Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
[your-256-bit-secret]
)
헤더와 페이로드 문자열을 합친 후, 알고리즘과 키를 이용해 함호화 한 값이다.
헤더와 페이로드는 누구나 쉽게 복호화할 수 있지만, Signature는 키가 없으면 복호화할 수 없어 보안상 안전하다.
🌟 프로세스
- 사용자는 로그인을 진행
- 서버는 비밀키를 사용해 JWT를 생성
- 클라이언트에게 생성한 토큰 전달
- 로그인 완료! 클라이언트는 받은 JWT를 로컬에 저장해 둠
- 사용자는 API 요청 시 헤더에 JWT를 넣어 보냄
- API 요청 헤더의 토큰을 확인하여 토큰이 위변조 되었거나, 만료 시각이 지나지 않은지 확인한 이후 인증된 사용자인지 체크
- 사용자에게 API 응답
🌟 장점
- 로컬에 토큰을 저장하기 때문에 서버에 인증 정보를 저장하지 않아도 된다. 세션은 서버에서 저장해야 하기 때문에 DB 용량 등에 영향을 끼친다.
- 키를 통해 서명하기 때문에 보안상으로 안전하다.
- 모바일 앱에서 사용하기 적합하다. -> 플팻폼 독립적으로 사용자 인증을 처리할 수 있다.
- 네트워크 부하가 적다.
- 토큰 기반 인증 방식은 HTTP의 비상태성(Stateless)를 그대로 활용할 수 있고, 확장성이 높아진다.
일반적으로 웹 어플리케이션은 서버 확장을 할 때 수평 확장을 사용하는데, 여러대의 서버가 요청을 처리할 때 별도의 작업을 해주지 않으면, 세션 기반 인증 방식은 세션 불일치 문제를 겪을 수 있다. 하지만 토큰은 서버가 직접 인증 방식을 저장하지 않고 클라이언트가 저장하는 방식을 사용하기 때문에 이런 문제가 없다.
🌟 단점
- 토큰의 크기가 커질수록 트래픽에 영향을 미친다.
-> 세션의 경우 Cookie 헤더의 세션 ID만 실어 보내면 되기에 트래픽을 적게 사용한다.
- 세션의 경우 모든 인증 정보를 서버에서 관리하기 때문에 보안 측면에서 조금 더 유리하다. 토큰의 경우 토큰이 만료되기전에 토큰을 탈취당하면 보안 상의 문제가 생긴다.
- Payload가 암호화 되어있지 않으므로, 민감한 데이터는 실을 수 없다.
- 토큰 만료 시 처리가 필요하다.