Access token은 사용자가 로그인에 성공하면 백엔드 API 서버가 프론트엔드에게 전송하는 것이다. 그 후 프론트엔드에서 로그인 한 사용자의 access token을 HTTP 요청에 첨부해서 서버에 전송하는 것이다.
HTTP 통신은 독립적이다. 따라서 이전에 어떤 HTTP 통신이 실행되었는지 알 수 없다. 즉 인증을 했는데 이전에 인증을 했는지 알 수가 없다는 것이다.
이미 로그인 된 상태인 것을 알기 위해서는 로그인 정보를 포함한 데이터를 HTTP 요청에 첨부해서 보내야한다. access token이 바로 그 로그인 정보다. 맨 위에서 기술했듯이 서버 API에서 access token을 생성하여 프론트에 쏴주면 프론트는 쿠키에 access token을 저장하고 있다가 그대로 access token을 가지고 다시 HTTP 요청을 서버에 보내고 서버는 access token을 복호화해서 얻은 JSON 데이터로 로그인한 사용자의 ID를 읽어들여 로그인 여부를 알 수 있는 것이다.
허접한 그림으로 설명하면 다음과 같다.
JWT
JWT(JSON Web Token)는 access token을 생성하는 기술 중 하나로 JSON 데이터를 token으로 변환하는 방식이다.
JWT의 구조
- header xxxxx 부분
→ 토큰 타입과 사용되는 해시 알고리즘을 지정한다.
- payload yyyyy 부분
→ JWT를 통해 전송하고자 하는 데이터 부분으로 HTTP 메시지의 body 부분과 비슷하다.
- signature zzzzz 부문
→ 서버에서 header, payload JWT secret을 암호화하여 프론트에 전송한다. 프론트에서 암호화한 토큰을 서버로 보내면 전송받은 JWT의 signature 부분을 복호화하여 서버에서 생성한 JWT가 맞는지 확인한다. 현실에서 사인의(sign) 의 역할과 비슷하다고 보면 된다.
합쳐서 xxxxx.yyyyy.zzzzz 모양이다. 여기서 header, payload 부분은 base64URL 로 코드화가 (복호화가 아니다.) 되어있으므로 민감한 정보는 넣지 않는것이 좋다.
PyJWT
파이썬에서도 JWT를 구현할 수 있게 해주는 라이브러리가 있는데 바로 PyJWT이다. 설치 명령어는 다음과 같다.
pip install PyJWT
import jwt
# PyJWT의 모듈을 import 한다.
data_to_encode = {'some': 'payload'}
# JWT의 Payload 부문에 들어갈 JSON 데이터다
encryption_secrete = 'secrete'
# JWT의 signature 부문을 암호화할 때 사용할 비밀키 지정
algorithm = 'HS256'
# JWT signature를 암호화할 알고리즘
encoded = jwt.encode(data_to_encode, encryption_secrete, algorithm=algorithm)
# JWT 생성
jwt.decode(encode, encryption_secrete, algorithms=[algorithm])
# 위에서 만들었던 JWT를 복호화하여 원본 payload 데이터를 읽어들인다.
{'some': 'payload'}