Spring/Spring
[JWT] JWT에 대해서
by 델버
2023. 1. 21.
JWT (Json Web Token)
- 클라이언트와 서버간에 정보를 JSON으로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준이다.
- 클라이언트가 서버에 요청할 때 토큰을 보내어 인증하는 방법에서 쓰인다. 이때 서버는 DB를 조회하지 않고 JWT가 유효한지 알 수 있기 때문에 토큰을 무상태(stateless)로 검증할 수 있다.
- https://jwt.io/introduction
특징
stateless
- 클라이언트가 로그인하면 서버는 JWT를 클라이언트에 보내고 클라이언트는 이 토큰을 저장한다. 이후 요청 시에 이 토큰을 함께 서버에 보내게 된다. 서버는 따로 토큰을 저장하지 않아도 되기때문에 무상태 stateless를 할 수 있다.
무결성
- JWT가 발급되고 나서 토큰의 내용이 변경되면 변조가 된 사실을 알 수 있다. 클라이언트의 Header와 Payload와 서버의 secret key를 가지고 토큰을 만들어 보내기 때문에 만약 클라이언트가 보낸 것이 다르면 변조되었다는 것을 알 수 있다.
구조 xxxx.xxxx.xxxx
Header
- Header는 JWT를 어떻게 검증하는가에 대한 내용을 담고있다. 토큰 유형(typ : JWT)과 알고리즘 정보(alg : HMAC SHA256 or RSA)로 구성된다.
{
"alg": "HS256",
"typ": "JWT"
}
Payload
- 토큰에 담을 정보(엔티티 및 추가 데이터)가 들어있다. 여기에는 여러 개의 클레임(claim)을 넣을 수 있고 이 속성들을 클레임 셋이라 부른다. 클레임에는 3가지 유형이 있다.
- https://www.rfc-editor.org/rfc/rfc7519#section-4.1
- 등록된 클레임(Registered claims): 이미 정의된 클레임이다.
- iss(Issuer): 토큰 발급자
- sub(Subject): 토큰 제목
- aud(Audience): 토큰 대상자
- exp(Expiration Time): 토큰 만료시간
- nbf(Not Before): 토큰의 활성시간, JWT가 실행되기 전의 시간을 식별한다.
- iat(Issued At): JWT의 발급된 시간을 식별한다.
- jti(JWT ID): JWT에 대한 고유한 식별자를 제공한다.
- 공개 클레임(Public claims): JWT를 사용하는 사람들이 마음대로 정의할 수 있다. 하지만 충돌 방지를 위해 IANA JSON 웹 토큰 레지스트리지에 정의하거나 이름을 URI로 정의해야 한다.
- 비공개 클레임(Private claims): 클라이언트와 서버 간의 협의 하에 사용되는 클레임이다.
- JSON은 Base64Url로 인코딩된다.
Signature
- 서명은 인코딩된 헤더, 인코딩된 페이로드, 비밀, 헤더에 지정된 알고리즘을 가져와서 생성한다.
- ex) HMAC SHA256 알고리즘은 이렇게 생성된다.
- HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
- signature는 도중에 메시지가 변경되지 않았는지 확인하는데 사용되며 개인 키로 서명된 토큰의 경우 JWT 발신자가 누구인지 확인할 수도 있다.
전체
- 모두 . 점으로 구분된 3개의 Base64URL 문자열이다.
- jwt.io 디버거를 사용하여 JWT를 디코딩, 확인 및 생성을 할 수 있다.
주의점
- Header와 Payload의 클레임은 암호화하지 않기 때문에 누구나 열어볼 수 있어서 중요한 정보를 넣으면 안된다. 또한 최소한 정보만 넣고 이름을 약자로 정해 토큰의 길이를 줄이는 것이 좋다.
- 토큰을 강제로 만료시킬 방법이 없기 때문에 클라이언트 쪽에서 제거(로그아웃)한다고 해도 누군가가 토큰을 탈취하면 토큰은 유효할 수 있다.
참고
댓글