JWT란?
Json Web Token의 약자로, 토큰을 통해 접근 권한을 확인 할 수 있기 때문에 디지털 서명이라고 볼 수 있다.
이전에는 서버의 session에 로그인한 회원을 저장하고, client에서 session id를 쿠키로 가지고 있어야 했다. 이 방식은 서버 프로그램이 여러 개일 때, 일관성을 유지하기 힘들다는 문제점이 있다. 따라서 따로 어디 저장할 필요 없이 로그인했다는 것을 확인할 수 있는 JWT가 탄생했다.
JWT의 구조
1. Header : Signature를 암호화한 알고리즘 정보 & 토큰 타입 정보
2. Payload : Claim
1) 등록된 Claim(필수X) : iss(발행자), exp(만료 시간), sub(제목), aud(청중) 등이 있다.
2) 개인 Claim
정보를 공유하기 위해 생성된 맞춤 클레임 ex) 사용자를 식별할 수 있는 id값
단, 민감한 개인정보는 넣지 않는다. base64방식은 복호화가 가능해서 누구에게나 노출될 수 있는 위험이 있다.
3. Signature : 각각 base64로 인코딩 된 Header, Payload에 자신의 Secret Key를 더해 Header에 정의한 방식으로 해싱 후, 그 값을 다시 base64로 인코딩한 값
*Secret Key는 토큰의 유효성을 체크하는 핵심 키로 노출되어서는 안 된다.
상세 구조
eyJraWQiOiJrZXkxIiwiYWxnojoiSFM1MTIiQf.ey
JzdWIiOiIxIiwiaWF0IxolNjcyOTgyNjExLCJleHA
iOjE2NzQ3OTcwMTF9.IxNyBPdPePnAiEpO25b2UPA
q780Vl9tzbVhUSnT-113vMov1X2e3PCqGpdGbhaJF
zQ_zwZ-4fZX6EWbsV8xvGA
- Header, Payload, Signature 각 부분을 '.'으로 구분하며, 각각 base64로 인코딩 된다.
- 민감한 정보를 전달한다기 보다는 서명된 토큰이라는 것이 핵심이다. 토큰에 서명한 사람이 맞다면 갖고 있던 Secret Key로 복호화해서 원하는 데이터를 추출해서 요청을 처리하고, 아니면 유효하지 않은 유저이므로 서버 접근을 제한한다.
Access Token과 Refresh Token
JWT는 주로 Access Token과 Refresh Token 2가지를 사용한다. 둘 다 JWT로, 구조는 같지만 유효 기간에서 차이가 있다. Access Token은 탈취가 되어도 피해를 최소한으로 하기 위해 유효 기간을 짧게 한다.
Access Token으로 주고 받다가 기한이 만료되면, Access Token과 Refresh Token을 보내서 새로운 Access Token을 발급 받도록 한다.
이때, 데이터베이스에는 사용자마다 AccessToken : RefreshToken 형태로 맵핑해서 저장한다. Refresh할 때, Access Token을 함께 받아서 맵핑된 값과 일치하는 지 확인 후에 발급해준다. 일치하지 않으면, 무효화 시켜서 사용자가 재로그인하도록 한다.
JWT 흐름
JWT 발급
사용자가 소셜로그인 혹은 아이디 비밀번호를 통해 로그인을 한다.
서버에서는 DB에 저장된 정보와 비교 후, 회원 가입된 유저면 Token을 발급해준다.
JWT로 Access 성공
로그인한 유저만 보낼 수 있는 요청같은 경우, Access Token과 요청을 함께 보낸다.
서버에서는 Secret Key로 Access Token이 유효한지 검증하고, 유효하면 응답 데이터를 보낸다.
JWT 만료로 Access 실패
Access Token의 유효 기간이 끝나면, 서버에서 만료됐다는 응답을 준다.
그러면 클라이언트에서는 Access Token과 Refresh Token을 함께 보내서 서버로 부터 새 Access Token을 발급받는다.
'Programming > Spring' 카테고리의 다른 글
[SpringBoot] @Transactional로 트랜잭션이 적용되는 원리 (0) | 2023.05.06 |
---|---|
[SpringBoot] 관점 지향 프로그래밍 AOP의 개념과 사용법 (0) | 2023.03.22 |
[SpringBoot] ResponseEntity의 개념과 구조 (0) | 2022.11.23 |
SpringBoot(2) - MyBatis 사용하기 (0) | 2022.06.10 |
SpringBoot(1) - SpringBoot 시작하기 (0) | 2022.06.10 |