실무 개발 최적화를 위한 고민을 계속 하던 중 하나의 방법으로 Spring Session에 대해서 자세히 알아보고 정리를 하였다.
그리고 혼자 생각하기 보다 내 개발 멘토이자 친한 친구인 상원님에게 실무에서의 고민을 공유하였는데 JWT를 사용하는 것도 고민해보라고 이야기 해주었다.
그저 듣기만 했던 JWT에 대해 정리해보고자 한다.
서버 개발 같은 경우 주로 프론트와 데이터를 주고 받거나 API 서비스 호출을 통하여 데이터를 주고 받는다.
대부분 XML과 JSON의 데이터 포맷을 가지고 통신하게 되는데 각각의 장단점이 있지만
내가 생각하는 JSON의 큰 장점인 객체에 바로 매핑된다는 점은 많은 프로그래밍에서 XML보다는 JSON 형태를 많이 사용하는 것 같다.
1) JSON Web Token?
Json Web Token은 말 그대로 Json 객체를 활용한 웹 인증서라고 볼 수 있다. 단순히 Json 객체 데이터를 주고 받는 것이 아닌 주고 받는 당사자 (클라이언트, 서버등)간 정보를 안전하게 전송하기 위한 방법이다.
디지털 서명을 통해 그 안전을 보장 받을 수 있고 그 서명은 HMAC 알고리즘 or RSA or ECDSA를 사용하여 공개/개인키 쌍을 사용한다.
2021.10.11 - [개발 지식/Java] - [JWT] 서명을 위한 알고리즘 HS256과 RS256
그 당사자들만의 서명은 JWT의 무결성을 확인할 수 있으며 다른 사용자에게는 데이터를 숨길 수도 있다.
2) 언제 JSON Web Token을 사용해야 하는가?
- 권한 부여: 사용자가 로그인하면 각 요청에는 JWT가 포함되므로 사용자는 해당 토큰으로 허용된 경로, 서비스 및 리소스에 접근 할 수 있다. 특히 SSO(Single Sign On)은 여러 도메인에서 쉽게 사용할 수 있어 JWT를 폭넓게 사용하고 있다.
- 정보교환 : JSON Web Token은 당사자 간에 정보를 안전하게 전송하는 방법이다. -> 해당 당사자들끼리 공개/개인 키를 쌍으로 암호화 할 수 있기 때문이다.
3) JSON Web Token 구조는 어떻게 될까?
JSON 웹 토큰은 점으로 구분된 3개의 부분으로 나타낸다.
- 헤더 (Header)
- 페이로드 (Payload)
- 서명 (Signature)
XXXXXX(Header).YYYYY(Payload).ZZZZZ(Signature)
3-1) 헤더(Heaer)
헤더는 JWT인 토큰 유형과 HMAC SHA256 또는 RSA와 같이 사용 중인 서명 알고리즘 두 부분으로 구성된다.
{
"alg": "HS256",
"typ": "JWT"
}
이 JSON은 Base64Url 인코딩 되어 JWT의 첫 번째 부분을 형성한다. -> XXXXXX
3-2) 페이로드 (Payload)
Token의 두번 째 부분은 데이터를 포함하는 Playload이다. 이 데이터는 세가지 타입으로 나뉜다.
- Registered claims (등록된 데이터)
: 필수적이지능 않지만 추천하는 값으로써 미리 정의된 데이터의 집합이다.
또 Registed claim은 iss(issuer, 발행인), exp(expiration time, 만료시간), sub(subject, 주제), aud (audience, 청중 즉 소비자), other로 구성되어 있다. - Public claims (공개된 데이터)
: 이 데이터는 사용자가 원하는 대로 정의할 수 있다. 그러다 충돌을 피하기 위해 IANA JSON Web Token을 정의하거나 충돌 방지 namespace를 포함한 URI가 정의 되어야 한다. - Private claims (비밀 데이터)
: 이 데이터는 당사자 간에 정보를 공유하기 위해 만들어진 맞춤형 데이터이다.
예를 들면 다음과 같다.
{
"sub": "1234567890",
"name": "erjuer01
"admin": true
}
이 페이로드는 Base64Url로 인코딩 되어 JWT의 두번째 부분을 형성한다. -> YYYYY
3-3) Signatrue (서명)
서명 데이터를 만들기 위해서는 인코딩 된 헤더, 페이로드, 개인키, 헤더에 지정된 알고리즘을 서명해야 한다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
서명은 메시지가 도중에 변경되지 않았는지 확인하는데 사용되며, 개인키로 서명된 토큰의 경우 JWT의 발신인이 누군지도 알 수 있다.
3-4) JWT로 변환
최종 JWT의 결과값은 점으로 구분된 3개의 Base64Url 문자열이며 SAML과 같은 XML 기반 표준과 비교할 떄 더 압축적이다.
즉 JSON 데이터 형태로 구성이 되어 있으므로 복잡함이 덜하다는 뜻이다.
4) JSON Web Token은 어떻게 동작할까?
로그인 및 인증시 서버에서 JSON Web Token이 변환된다. 토큰은 자격증명이자 보안 문제를 방지하기 위해 많은 주의를 기울여야 한다. 일반적으로 토큰을 필요한 시간보다 오래 보관해서는 안된다.
또한 중요한 세션 데이터를 브라우저 저장소에 저장해서는 안됩니다.
클라이언트가 리소스에 액세스 하기 위해 헤더에서 JWT를 전송해야 한다. 헤더 내용은 다음과 같다.
Authorization: Bearer <token>
토큰이 인증 헤더로 전송되면 쿠키를 사용하지 않으므로 코르스 도메인 문제가 발생하지 않습니다.
그리고 서명된 토큰의 경우 토큰에 포함된 모든 정보는 변경할 수 없더라도 다른 당사자에게 노출된다. 그렇기 때문에 비밀 정보를 토큰안에 넣어서는 안된다.
5) JSON Web Token을 사용하는 이유는 무엇일까?
SWT와 SAML과 비교하여 JWT의 장점에 대해서 풀어보자.
일단 JSON은 XML보다 복잡 하지 않으며 encode 사이즈도 작다. 이 장점은 HTML과 HTTP 환경에서 좋다.
더 나아가 SWT는 HMAC 알고리즘을 사용하는 공유 암호로만 대칭 서명할 수 있지만
JWT와 SAML 토큰은 서명을 위해 X.509인증서 형식의 공개/개인키 쌍을 사용할 수 있고 JSON 서명의 단순성과 비교 했을 떄 XMl을 XMl 디지털 서명으로 서명하는 것은 매우 어렵다.
또 내가 서두에 적었던 JSON의 장점으로 대부분 프로그래밍 언어에서 JSON parser를 이용하면 XML보다 쉽게 객체에 바로 매핑이 된다.
끝.
Reference site)
https://auth0.com/docs/security/tokens/json-web-tokens
'개발 지식 > Backend' 카테고리의 다른 글
[Cache] Ehcache vs Caffeine Cache (4) | 2022.09.07 |
---|---|
[WebFlux] WebFlux Kotlin MapStruct 적용 (0) | 2022.05.10 |
[RPC] gRPC 프레임 워크 적용기 (3) | 2022.05.09 |
[Log] Apache Log4j2 취약점 발견 및 원인 (0) | 2021.12.13 |
[JWT] 서명을 위한 알고리즘 HS256과 RS256 (0) | 2021.10.11 |
댓글