로그인한 사용자는 어떻게 계속 로그인 상태를 유지하면서 권한이 필요한 우리 서비스를 돌아다니는걸까?
JWT 는 회원 로그인이 완료 되었을때 발행되는 토큰을 말한다. JWT에는 암호화 된 회원정보가 들어있으며 복호화를 통해 사이트내의 서비스를 사용할 수 있는지 확인 (인가 : Authorizationathon ) 하는데 사용한다.
JWT는 JSON Web Token의 약자로 전자서명 된 URL-safe (URL로 이용할 수 있는 문자로만 구성된)의 JSON 이다.
JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다. 이 인증 과정을 통해 사용자는 로그인 상태로 우리 서비스를 돌아다닐 수 있다.
JWT는 헤더(header), 정보(payload), 서명(signature) 구조로 이루어져 있다.
토큰에는 [유저 정보]와 [secret key], [적용하고자 하는 알고리즘]을 넣어서 발행한다. 아래는 유저 아이디가 [1]이고, 시크릿키는 [secretkey]이며 [HS256] 알고리즘을 사용해 토큰을 발행하겠다는 명령어 이다.
import jwt
$ jwt.encode({<유저정보>}, <시크릿키>, algorithm = '특정 알고리즘') # 명령어 구성
$ token = jwt.encode({'user_id': 1}, 'secretkey', algorithm = 'HS256') # 실제 명령어 작성
$ token # 발행된 토큰
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.B9XWphE_QU5UZAT8jhKg_jYNGmZOfSL1gcl-3kZeuoI'
발행된 토큰을 넘기면 되는데, 토큰 현재 타입이 bytes
로 되어 있기 때문에 문자열 형태로 바꾸어 (decode) 전달해줘야 한다.
$ token.decode('utf-8') # 문자열로 디코딩
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.B9XWphE_QU5UZAT8jhKg_jYNGmZOfSL1gcl-3kZeuoI'
그리고 bcrpyt와 다른 점은 토큰을 확인할 때, 토큰을 jwt로 디코딩하면 기존에 입력했던 유저정보가 반환된다.
$ jwt.decode(token,'secretkey',algorithm = 'HS256')
{'user_id': 1} # 기존 유저정보 반환
그렇기 때문에 디코딩할 수 있는 정보에 대한 보안이 중요하다고 하는데, Django의 경우 secret key가 내부 settings.py에 기본적으로 작성되도록 되어 있어 이렇게 하면 보안에 좋지 않다고 한다. 실제 프로젝트 진행 시 따로 파일을 만들어 관리해야 좀 더 보안성을 높일 수 있다고 함.
# my_settings.py
SECRET_KEY='secret'
ALGORITHM = 'HS256'
SECRET_KEY와 ALGORITHM은 분리된 파일에 보관하여 Import하여 사용한다.
>>> from .my_settings import SECRET_KEY, ALGORITHM
(알고리즘은 선택전, 시크릿키는 필수!)
SECRET_KEY가 담긴 파일은 꼭 .gitignore에 포함하여 git에 업로드 되지 않도록 주의