프로젝트에서 JWT 토큰을 사용하기로 했는데 지금까지 프론트로 연동만 해봤지 뭔지는 모른다.
심지어 J 가 자바는 아닐까? 라고 생각하기도 했다.
웃기죠? JSON Web Token 입니다..
1. JWT
JSON 객체에 인증에 필요한 정보들을 담은 후 비밀키로 서명한 토큰
인증 (Authentication) & 권한허가 (Authorization) 방식
JWT 토큰 인증 방식은 비밀키로 암호화를 하기 때문에 클라이언트와 서번는 안전하게 통신이 가능하다.
일반적으로 사용자 인증에 사용되며, 사용자가 로그인하면 서버는 인증 정보를 담은 JWT를 생성하여 클라이언트에게 전달한다.
이후 클라이언트가 이 토큰을 저장하고, API 요청 시마다 토큰을 함께 전송함으로써 인증을 처리한다.
사용자가 아이디와 비밀번호를 이용해 서버에 로그인 요청을 보냄
-> 서버는 비밀키를 사용해 json 객체를 암호화한 JWT 토큰을 발급
-> JWT를 헤더에 담아 클라이언트로 보냄
-> 로그인 인증에 성공한 클라이언트는 Access, Refresh Token 두 개를 서버로부터 받아 로컬에 저장
-> 헤더에 Access Token을 넣고 API 통신
-> 일정 기간이 지나 Access Token의 유효기간이 만료
-> 권한이 없는 사용자가 되고, 유효기간이 끝난 토큰을 받은 서버는 401 에러 발생
-> 헤더에 Access Token 대신 Refresh Token 을 넣어 API 재요청
-> Refresh Token으로 사용자의 권한을 확인한 서버는 헤더에 새 Access Token을 넣어 응답
-> Refresh Token도 만료되었으면 서버는 동일하게 401 에러를 발생, 클라이언트는 재로그인 필
매번 JWT를 헤더에 넣어서 보내는게 비효율적인 것 같지만 매번 인증 과정을 걸쳐야 하는 이유는 HTTP의 특성 때문이다.
HTTP는 conectionless 하고 stateless 하다는 특성이 있어,
한 번 통신이 일어나고 나면 연결이 끊어지고 다시 연결해도 이전 상태를 유지하지 않아 과거 정보를 보냈었는지 기억하지 못한다
즉 화면을 이동해 새로운 API를 요청하면 다시 신뢰할만한 사용자인지 인증하는 과정을 거친다.
매번 사용자가 인증하는 과정으로 통신이 느려질 수 있어서, 인증된 사용자가 어느 정도 기간 동안 재인증을 하지 않아도 되도록 만든게 Access Token 이고, 유효기간이 짧다.
<-> Refresh Token
리프레시 토큰의 유효기간은 길다.
평소에 API 통신할 때는 Access 를 사용하고, Refresh 는 Access 가 만료되어 갱신될 때만 사용된다.
즉 JWT 토큰의 탈취 위험을 최소화하고, 빈번한 재로그인 방지를 위해 사용된다.
그래도 여전히 탈취 위험이 존재하기에 OAuth 에서는 Refresh Token Rotation 을 통해 Access Token을 재요청할 때마다 Refresh Token도 새로 발급받는 방법을 제안한다. 탈취자가 가지고 있는 Refresh Token은 더이상 만료 기간이 긴 토큰이 아니게 되니까 불법적인 사용의 위험은 줄어든다.
2. JWT의 구조
Header, Payload, Signature 총 3가지 요소로 구성된 문자열로,
각 요소는 Base64URL 방식으로 인코딩 되어있으며 . 으로 구분됩니다
Header.Payload.Signature
JSON Web Tokens - jwt.io
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
jwt.io
https://logto.io/ko/jwt-decoder
JWT 디코더 & 인코더 (JWT decoder & encoder) | 안전하고, 간단하며, 사용자 친화적
JWT 를 신속하게 온라인으로 디코드하고 인코드하며, 그들의 서명을 검증하세요. 다양한 알고리즘을 사용한 JWT 예제와 단계별 JWT 구현 가이드를 탐색해보세요.
logto.io
1) Header
헤더는 토큰의 타입(typ)과 해싱 알고리즘 정보(alg)를 담고 있다.
2) Payload
실제 데이터를 담고 있는 부분이며, 이 안의 항목을 클레임(Claim)이라고 부른다.
클레임은 Key/Value 형태로 된 값을 가진다.
저장되는 정보에 따라 클레임은 총 3가지 유형으로 구분된다.
등록된 클레임 / 공개 클레임 / 비공개 클레임
| iss | 토큰 발급자 Issuer |
| sub | 토큰 제목 Subject |
| aud | 토큰 대상자 Audience |
| exp | 토큰 만료 시간 Expiration Time |
| nbf | 토큰 활성 날짜 Not Before |
| iat | 토큰 발급 시간 Issued At |
| jti | JWT 식별자 JWT ID |
exp, nbf, iat 등의 시간 정보는 Unix Timestamp 로 표기!
Payload는 암호화되지 않기 때문에 누구든 디코딩이 가능해 민감한 정보는 절대 포함해서는 안 된다.
3) Signature
Header와 Payload를 결합한 문자열에 헤더에서 선언한 알고리즘과 키를 이용해 암호화한 값이다.
토큰의 무결성을 보장하고, 위변조 여부를 확인하는 데 사용된다.
JWT가 신뢰할 수 있는 서버에서 발급되었는지 검증하는 핵심적인 역할을 한다.
즉 누군가 Payload의 내용을 변조해도, 서명을 재생성할 수 없기 때문에 서버는 해당 토큰을 신뢰하지 않고 거부
3. JWT의 장단점
장점
- 로컬에 저장하기 때문에 서버 용량에 영향을 끼치거나 받지 않음
- 하나의 토큰으로 다양한 클라이언트(웹, 앱)에서 일관된 방식으로 사용 가능
- 토큰 자체에 필요한 모든 인증 정보가 포함되어 있어, 별도 DB 조회 없이 인증 가능
- 서버 간의 세션 공유가 필요하지 않기 때문에, 확장성이 뛰어남
- Signature로 토큰의 위변조 여부를 검증 가능해 무결성이 보장됨
단점
- 클라이언트가 토큰을 보유하므로, 탈취 시 보안에 취약함
- JWT에 포함되는 데이터가 많아질수록 토큰 크기가 증가해, 네트워크 트래픽에 부담을 줄 수 있음
- 토큰은 발급되면 만료 기간 변경이 불가능하므로 토큰 만료 처리를 구현해야 함
'1일1티스토리' 카테고리의 다른 글
| 240902 - 클라우드 컴퓨팅 개념 (0) | 2025.09.02 |
|---|---|
| 250901 - 헛헛 (0) | 2025.09.01 |
| 250622 - github & hugging-face 에 학습 시킨 모델 업로드하고 토큰 관리하기 (3) | 2025.06.23 |
| 250319 - Port 5173 is in use, trying another one... (0) | 2025.03.19 |
| 250318 - set과 백준 25757번 (0) | 2025.03.18 |