#JSON Web Token (JWT)
예전에 어쩌다 보니 인증이 꼬리에 꼬리를 물면서 인증정보를 계속 전달하는 로직을 개발 한적이 있었습니다.
예를 들면 비밀번호를 재 검증 후, 검증이 올바르면 해당 인증 값을 가지고 다시 이메일 인증을 받고,
이메일 인증이 올바르면 해당 인증 값을 가지고 다시 다른 인증을 받고…
이전 인증 정보가 올바르지 않으면 다음 단계의 인증을 받을 수 없도록 처리 하려고 하다보니,
토큰 기반의 인증방식을 검토하게 되었고, JWT 인증이 존재한다는 걸 알게 되었다. 물론 그 당시에는 쓰진 않았지만…
최근 들어 MSA 쪽을 공부하다 보니 기존 세션, 쿠키 기반으로는 여러 서버를 다중 도메인으로 운영 하는데 한계가 있어,
JWT 기반의 인증을 다시 검토 하게 되었습니다..
JWT?
JWT를 간단히 정의 하면 서비스 간 JSON 객체를 이용하여 정보를 안전하게 전달하기 위한 웹 표준 (RFC 7519) 을 의미합니다.
HMAC 알고리즘이나, RSA 등 다양한 방식을 지원하는 전자 서명을 통해 토큰의 무결성은 검증 할 수 있습니다.
##구조
JWT 의 구조를 살펴보면 위와 같이 . 을 구분자로 header, payload, signature 3가지 문자열로 구분할 수 있습니다.
Header(헤더)
Header는 JWT 토큰을 해석하기 위한 정보가 저장된 곳으로, 아래의 2개의 정보로 구성됩니다. base64로 인코딩 됩니다.
{
alg : "HS256",
typ : "JWT"
}
alg: 서명 암호화 알고리즘 정보 입니다. 주로 HMAC SHA256 이나 RSA가 주로 사용됩니다. 예제에서는 HMAC SHA256를 사용하고 있습니다. typ: 토큰의 유형을 알려줍니다. 예제에서는 JWT 인 것을 알 수 있습니다.
Payload(정보)
Payload는 실제 토큰에 담길 정보가 여러 개의 클레임(Claim)으로 구성되어 저장됩니다. 암호화 되지 않으므로 중요한 정보를 저장 하지 않는 것이 좋습니다. base64로 인코딩 됩니다.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
클레임은 크게 Registered, Public, Private 3가지로 분류 할 수 있습니다.
Registered claims(등록된 클레임)
JWT에 사전에 이름이 정의 된 클레임으로, 필수 값은 아닙니다. 자세한 내용은 아래와 같습니다.
- iss: 토큰 발급자 (issuer)
- sub: 토큰 제목 (subject), 토큰의 주제를 설명
- aud: 토큰 대상자 (audience)
- exp: 토큰의 만료시간 (expiraton), 숫자 형식으로 유효기간이 지난 토큰은 사용 불가능 하도록 처리 합니다.
- nbf: Not Before 를 의미하며, 만료시간과 마찬 가지로 숫자 형식이며, 해당 시간 이전에는 사용라지 않도록 처리 합니다.
- iat: 토큰이 발급된 시간 (issued at)
- jti: JWT ID, 주로 중복적인 처리를 방지하기 위하여 사용됩니다
Public claims(공개 클레임)
공개용 정보를 위해 사용 되며, 일반적으로 충돌 방지를 위해 URI 형태로 구성됩니다.
Private claims(비공개 클레임)
토큰을 주고 받는 양측에서 사전 협의된 이름으로 사용되는 클레임 입니다.
Signature(서명)
JWT의 위변조를 검증하기 위한 부분입니다. base64로 인코딩한 Header, Payload 값을 합친 후, 헤더의 alg에서 정의된 알로리즘으로 인코딩하여 생성 합니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Token 동작 방식
- 응용 프로그램 또는 클라이언트에서 로그인 등을 통해 권한을 요청
- 권한이 부여되면 서버에서 액세스 토큰을 반환
- 응용프로그램은 해당 엑세스 토큰을 사용하여 API에 접근
- 엑세스 토큰의 수명이 만료되면 토큰을 재 발급하여 사용
토큰의 수명이 길 경우 토큰을 탈취하여 사용할 위험이 생긴다.
하지만 수명을 짧게 할 경우 매번 로그인등을 통해 재발급 해야하는 불편함이 발생한다.
그래서 일반적으로 접근 권한이 부여된 수명이 짧은 Access Token,
Access Token 을 재 발급 받기 위한 수명이 긴 Refresh Token 으로 구성하여 사용하는데
해당 내용은 다음에 기회가 되면 정리 하려고 합니다.
참고사이트:
[https://jwt.io/]
[https://velopert.com/2389]
[https://blog.outsider.ne.kr/1160]
[https://covenant.tistory.com/201]