Django/Django Rest Framework
23. DRF JWT란
S.T.Lee
2022. 7. 18. 21:31
Session 인증 방식
- 브라우저에서 사용자가 인증(Authentication)을 수행하면 서버에서는 사용자의 정보를 저장하고
- 그 응답으로 JESSIONID라는 키를 이용해 클라이언트(사용자) 브라우저의 쿠키에 세션 정보를 저장한다.
- 이후 클라이언트는 브라우저 쿠키에 저장된 JESSIONID로 저장된 세션 정보를 이용해 인가(Authorization)된 정보에 접근할 수 있게 된다.
Token 인증 방식
- 사용자가 인증을 수행하면 서버에서 토근을 생성 후 저장하지 않고(stateless) 토큰값을 사용자의 브라우저에 응답한다.
- 발급된 토큰을 사용자가 인가된 사용자만 사용할 수 있는 서비스를 요청할 때 함께 보내게 되고, 서버에서 이 토큰을 의미 있는 값(ex. 사용자 정보)으로 해석하게 된다. 그리고 이 값으로 사용자를 인증하게 된다.
- 토큰은 username, user_id 등 사용자를 설명할 수 있는 데이터를 포함하게 된다.
- 이렇게 사용자를 설명할 수 있는 데이터를 클레임(claim)이라고 한다.
- claim은 데이터 한줄 한줄을 의미한다.
- 즉, user_id, username 모두 claim이다.
JWT(Json Web Token) 알아보기
- JWT 토큰 구조는 HEADER.PAYLOAD.VERIFY_SIGNATURE로 이루어져 있다.
- 각 데이터는 온점(.)으로 구분된다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- HEADER
- HEADER는 JWT를 검증하는데 필요한 정보를 가진 데이터이다.
- VERIFY_SIGNATURE에 사용한 암호화 알고리즘과 토큰 타입, key의 id등의 정보를 가지고 있다.
- 즉, 암호화된 값은 아니다.
HEADER 정보
{
"typ": "JWT", # 토큰 타입
"alg": "HS256" # 알고리즘
}
- PAYLOAD
- 인증에 필요한 데이터를 저장한다.
- 대부분의 경우 Claim에 username 또는 user_id를 포함한다.
- 또한 토큰 발행시간(iat)와 토큰 만료시간(exp)이 있다.
PAYLOAD 정보
{
"token_type": "access", # 토큰의 종류. 여기서는 access 토큰입니다.
"exp": 1656293275, # 토큰의 만료시간입니다. (Numeric Date)
"iat": 1656293095, # 토큰의 발행시간입니다. (Numeric Date)
"jti": "2b45ec59cb1e4da591f9f647cbb9f6a3", # json token id 입니다.
"user_id": 1 # 실제 사용자의 id값이 들어있습니다.
}
- VERIFY SIGNATURE
- header와 payload는 암호화 되지 않고 단순히 Json -> UTF-8 -> Base64 형식으로 변환된 데이터이다.
- 따라서 header와 payload만으로는 토큰에 대한 진위여부를 판단할 수 없다.
- 따라서 VERIFY SIGNATURE로 토큰 자체의 진위여부를 판단한다.
- VERIFY SIGNATURE는 Base64UrlEncoding된 header와 payload의 정보를 합친 뒤 SECERET_KEY를 이용하여 Hash를 생성하여 암호화 한다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
SECRET_KEY
)