티스토리 뷰

JWT

JWTJson 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token을 말한다.


세션은 서버에 사용자 정보를 저장하기 때문에 서비스를 이용하는 사용자가 많으면 그만큼 저장할 공간도 더 필요하며,
분산서버에서는 세션을 공유(A서버에 저장된 세션 ID로 B서버에서 인증)하는데 어려움이 존재하는 등의 단점이 존재한다.


이런 세션의 단점을 해결하기 위해서 토큰으로 인증하는 방법을 사용할 수 있는데, 유저가 로그인을 하면 서버에서는 토큰을 생성한 뒤에 저장하지 않고(stateless) 토큰값을 내려준다. 사용자는 이 토큰 값과 함께 서버에 요청하면 A서버든, B서버든 상관없이 토큰 값을 토대로 유저를 인증한다.


토큰 방식의 장점

  1. 세션관리를 할 필요가 없어 별도의 저장소가 필요하지 한다.
  2. 서버 분산&클러스터 환경과 같은 확정성에 좋다.

토큰 방식의 단점

  1. 한번 제공된 토큰은 회수가 어렵다. 세션의 경우에는 서버에서 세션을 삭제하면 브라우저의 JSESSIONID는 무용지물이 되어버리는 반면, 토큰은 세션을 저장하지 않기 때문에 한 번 제공된 토큰을 회수할 수 없다. 그래서 보통 세션의 유효기간을 짧게 한다.
  2. 토큰에는 유저의 정보가 있기 때문에 민감한 정보를 토큰에 포함시키면 안 된다.(패스워드, 개인정보)

JWT의 구조

JWTHEADER.PAYLOAD.SIGNATURE의 구조를 갖는다.

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZXMiOl.hHkvviDzMIx8EkXUTZsNLWGy51p2 bVnJknEC0HYxMaRkXGQJdIWqIX1Rv8rGK6bMq6mYyGES3jxNJVPz33wvEQ

Header

HeaderJWT를 검증하는데 필요한 정보를 가진 객체이다.
Signature에 사용한 암호화 알고리즘이 무엇인지, KeyID가 무엇인지에 대한 정보를 Json으로 변환해서 UTF-8로 인코딩한 뒤, Base64 URL-Safe로 인코딩한 값이 들어가 있다. 결과 값이 다소 난해한 문자로 보이지만, 암호화된 값은 아니다.



Payload

Payload는 실질적으로 인증에 필요한 데이터를 저장하며, 데이터의 필드들을 Claim이라고 한다.
인증할 때 Payloadusername으로 유저 정보를 조회해야 하기 때문에 Claimusername을 포함하고 있다.
Header와 마찬가지로 암호화된 값이 아닌 Json으로 바꾼 뒤 UTF-8로 인코딩하고 Base64로 변경한 데이터일 뿐이다.



Signature

JWT의 구조에서 가장 마지막에 있는 Signature는 토큰 자체의 진위여부를 판단하는 용도로 사용된다. SignatureHeaderPayload를 합친뒤 비밀키로 Hash를 생성하여 암호화한다.


Header.Payload 값을 SecretKeyHashing하고 Base64로 변경한다.


Key Rolling

JWT의 토큰 생성 메커니즘을 살펴보면 Secret Key의 노출은 곧 모든 데이터의 유출이라는 것을 알 수 있다.
이런 문제를 방지하기 위해서, 여러 개의 Secret Key를 주기적으로 추가/삭제하며 변경하는 것을 Key Rolling이라 말한다. 이 경우 Secret Key가 노출되어도 다른 Secret Key와 데이터는 안전하다. (필수 X)


Key Rolling에서는 여러개의 Secret Key가 존재한다. Secret Key 1개에 UniqueID(kid 혹은 key id라고 부름)를 연결시켜 둔다. JWT 토큰을 만들 때, 헤더에 kid를 포함하여 제공하고, 서버에서 토큰을 해석할 때 kidSecret Key를 찾아서 Signature를 검증한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함