인증
요청한 클라이언트가 자신이 주장하는 사용자와 같은 사용자인지를 확인하는 과정
인가
그 대상 즉, 클라이언트가 request 작업이 해당 클라이언트에게 허가된 작업인지를 확인하는 것
예전에는 인증, 인가를 DB에 직접 접근하는 세션(Session)을 이용하였는데,
이 방식은 동시 사용자가 많을때, 서버에 과부하가 걸릴 수 있기 때문에 문제가 있었다.
이러한 문제점을 JWT를 통해 쉽게 처리할 수 있다.
(처음 로그인할때, token을 주어 다음 Authorization을 빠르게 처리)
python에서는 PyJWT 라이브러리를 통해 지원을 하고 있다.
JWT는 세 파트로 나누어지며, 순서대로 헤더 (Header), 페이로드 (Payload), 서명 (Sinature)로 구성된다.
Base64
인코딩의 경우 “+”, “/”, “=”이 포함되지만 JWT는 URI에서 파라미터로 사용할 수 있도록 URL-Safe 한 Base64url
인코딩을 사용한다.
예를들어,
access_token = jwt.encode({'id': 19}, 'secret', algorithm='HS256')
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTl9.oJPc2ULv5OUuJkMUr7-tE9YZJKzU2broxWw_oB6x1yw
PyJWT 라이브러리를 통해 위와 같은 token을 생성하였다.
{
"typ": "JWT",
"alg": "HS256"
}
Header에는 토큰의 타입과 해시 암호화의 알고리즘으로 구성되어 있다.
위의 정보를 Base64url
으로 인코딩하면 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.
{
"id": 19
}
Payload는 그 안에 담는 정보의 한 ‘조각’ 을 클레임이라고 부르고, 이는 name / value
의 한 쌍으로 이뤄져있다.
토큰에는 여러개의 클레임들을 넣을 수 있다.
클레임의 정보는 등록된 (registered) 클레임, 공개 (public) 클레임, 비공개 (private) 클레임으로 세 종류가 있다.
마찬가지로 Base64url
으로 인코딩하면 eyJpZCI6MTl9
.
마지막으로 Signature는 secret key를 포함하여 암호화(encrypt)되어 있다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
) secret base64 encoded
위와 같은 구조로 이루어져 있다.
Base64url
로 인코딩한 헤더와 내용을 더하고, secret key(역시 인코딩) 또한 포함하여,
해당하는 알고리즘(HS256
)으로 해시하여 값을 만든다.
그렇기 때문에 이 secret key가 노출되지 않으면,
Payload를 조작하여 보내도 Signature가 다르기 때문에 Authorization을 할 수 있다.
참고로 jwt사이트에 접속하면 해당 token에 대한 정보를 알 수 있다.
참조
(https://kibua20.tistory.com/83)
(http://www.opennaru.com/opennaru-blog/jwt-json-web-token/)