본문 바로가기

Spring/Security

📝 JWT 토큰(JSON Web Token)

1. JWT(JSON Web Token)

JSON 객체를 통해 안전한게 정보를 전송할 수 있는 웹 표준(RFC7519)

 

2. JWT의 구조

'.(마침표)'를 구분자로 암호화된 세 가지 데이터가 붙어있는 구조

 

 

1) 헤더(Header)

  • alg: Verify Signature를 만드는 데 사용된 알고리즘
  • typ: 토큰의 타입. 이 부분은 언제나 고정값 'JWT'

 

2) Payload: DATA

- 실제로 전달할 정보

- payload는 Base 64로 디코딩 하면 JSON 형식으로 여러 정보들을 포함하고 있음

(이 토큰을 누가 누구에게 발급했는지, 이 토큰이 언제까지 유효한지, 서비스가 사용자에게 이 토큰을 통해 공개하기를 원하는 내용 등)

- 특히 토큰에 담긴 사용자 정보 등의 데이터를 claim이라고 하는데 사용자가 로그인을 하고 나서 받는 토큰에 이러한 claim을 통해 해당 사용자에 대한 정보들이 포함되어 온다.

 

  • sub: Subject를 줄인 말로 토큰의 주인을 의미. sub는 ID처럼 유일한 식별자여야 함
  • iss: Issuer를 줄인 말로 토큰을 발행한 주체
  • iat: issued at을 줄인 말로 토큰이 발행된 날짜와 시간
  • exp: expiration을 줄인 말로 토큰이 만료되는 시간

 

 

3) 서명(Verify Signature)

- 위 변조를 방지하기 위한 값

- 토큰을 발행한 주체가 Issuer가 발행한 서명으로 토큰의 유형성 검사에 사용됨

- (header + payload + 서버에 감춰놓은 비밀값)을 헤더에서 정한 알고리즘에 통과시키면 Verify Signature가 생성됨

(서버에 감춰놓은 비밀값이 없으면 디코딩은 의미없는 것)

 

3. 구동 흐름

 

1) 클라이언트가 서버에 로그인 요청

2) 서버는 로그인 요청 완료 시 클라이언트에게 JWT를 생성하여 전달

3) 클라이언트는 JWT를 헤더에 담아서 요청

4) 서버는 클라이언트 요청 헤더에 있는 토큰 값(토큰 header, payload 값)과 ‘서버에 감춰놓은 비밀 값’을 알고리즘에 넣고 계산된 결과값이 3번 서명값과 결과가 일치하는지 확인(만약 2번 payload의 값이 조금이라도 수정되었다면 값이 맞지 않을 것)

5) 결과값도 일치하고 유효한 토큰이라면 그 사용자는 로그인된 회원으로서 인가를 받음

 

 

4. 장점

1) 타 토큰들과 달리 토큰 자체에 데이터를 가지고 있기 때문에 사용자가 인증 요청을할 때 필요한 정보를 전달하는 객체로 사용할 수 있음

2) 로그인한 사용자가 이후 요청을 할 때마다 사용자 정보를 담은 토큰을 가져가기 때문에 서버는 요청이 들어올 때마다 일일이 DB를 조회할 필요가 없다

3) 토큰 기반의 로그인을 하게 되면 세션이 유지되지 않는 다중 서버 환경에서도 로그인을 유지할 수 있게 되고 한 번의 로그인으로 유저정보를 공유하는 여러 도메인에서 사용할 수 있다

 

5. 단점

  • 서버는 클라이언트의 요청 헤더의 토큰을 검사해주는 역할에 그치므로 사용자의 로그인을 취소시키는 등의 통제 불가

 

6. 보완 방법

  • RefreshToken 이용하기
    • 수명이 몇 시간이나 몇 분 이하로 짧은 access token과 보다 긴 몇 주 정도로 설정된 refresh token 발급
    • 두 토큰을 발급하고 클라이언트에게 보내고 나서 refresh token은 상응값을 DB에도 저장
    • 클라이언트는 access token의 수명이 다하면 refresh token을 보내는데 서버는 이것을 DB에 저장된 값과 대조해보고 일치한다면 새 access token을 발급
    • 이 refresh token만 안전하게 관리된다면 이게 유효할 동안은 새로 로그인할 필요 없이 새 access token을 발급받는 것

 

👉🏻 즉, refresh token은 access token을 재발급받을 때 쓰는 것

결과적으로 access token이 탈취당하고 조작되어도 refresh token을 발급받지 못하기 때문에 로그인 유지 불가

어떤 사용자를 강제 로그아웃 시키는 것도 refresh token을 DB에서 삭제하여 토큰 갱신이 안되게 하는 방식으로 가능

 

7. 한계점

  • refresh token을 갱신하지 못하더라도 access token의 짧은 수명 동안 내에서는 통제할 방법이 없음