비밀번호 암호화 구현과 JWT(2)

.·2020년 5월 18일
2

Coding

목록 보기
22/33

1. JWT (Json Web Token)

로그인한 사용자는 어떻게 계속 로그인 상태를 유지하면서 권한이 필요한 우리 서비스를 돌아다니는걸까?

JWT 는 회원 로그인이 완료 되었을때 발행되는 토큰을 말한다. JWT에는 암호화 된 회원정보가 들어있으며 복호화를 통해 사이트내의 서비스를 사용할 수 있는지 확인 (인가 : Authorizationathon ) 하는데 사용한다.

JWT는 JSON Web Token의 약자로 전자서명 된 URL-safe (URL로 이용할 수 있는 문자로만 구성된)의 JSON 이다.

JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다. 이 인증 과정을 통해 사용자는 로그인 상태로 우리 서비스를 돌아다닐 수 있다.

2. JWT의 구조

JWT는 헤더(header), 정보(payload), 서명(signature) 구조로 이루어져 있다.

  • header : 타입(JWT)과 알고리즘(BASE64 같은)을 담는다.
  • payload : 보통 유저정보(id같은)와 만료기간이 객체형으로 담긴다.
  • signature : header, payload를 인코딩 한 값을 합친뒤 SECRET_KEY로 해쉬한다.

3. import jwt, 토큰 확인하기

토큰에는 [유저 정보]와 [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'

4. 프론트엔드 개발자에게 전달하기

발행된 토큰을 넘기면 되는데, 토큰 현재 타입이 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에 업로드 되지 않도록 주의

5. Summary

  1. 유저가 로그인 했을때 입력값이 DB의 회원정보와 일치할때 JWT를 발급한다.
  2. 프론트엔드에서는 JWT를 로컬/세션스토리지에 저장
  3. 유저가 회원인증이 필요한 서비스에 접근했을때, 프론트는 요청을 보낼때 header, authorization에 토큰값을 담아 보낸다.
  4. 백엔드 에서는 받은 토큰값을 복호화 하여 유저정보를 확인
  5. DB에서 해당정보가 있는지 확인, 있다면 해당 서비스를 이용할수 있도록 함
profile
.

0개의 댓글