코드 그라데이션

JWT 소개 본문

SpringBoot [예제] 블로그 만들기/시큐리티, JWT 입히기

JWT 소개

완벽한 장면 2023. 10. 18. 13:31

JWT

- 발급받은 JWT를 이용해 인증 하려면 HTTP 요청 헤더 중에 Authorization 키값에 Bearer + JWT 토큰값을 넣어서 보내야 한다.

 

 

JWT는 . 을 기준으로 헤더(header), 내용(payload), 서명(signature)으로 이루어져 있다.

 

헤더에는 토큰의 타입과 해싱 알고리즘을 지정하는 정보를 담는다.

 

헤더의 구성

 

내용에는 토큰과 관련된 정보를 담는다. 

내용의 한 덩어리를 클레임claim이라고 부르며,클레임은 키값의 한 쌍으로 이루어져 있다. 

클레임은 등록된 클레임, 공개 클레임, 비공개 클레임으로 나눌 수 있다.
등록된 클레임(registered claim)은 토큰에 대한 정보를 담는 데 사용한다.

 


공개 클레임(Public claim)은 공개되어도 상관없는 클레임을 의미한다.

- 층돌을 방지할 수 있는 이름을 가져야 하며 보통 클레임 이름을 URI로 짓는다.

비공개 클레임(Private claim)은 공개되면 안 되는 클레임을 의미한다.

- 클라이언트와 서버 간의 통신에 사용된다.

 

예시


iss, iat, exp는 JWT 자체에서 등록된 클레임이고,

URI. 네이밍된 https://shinsunyoung.com/jwt_claims/is_admin은 공개 클레임이다. 그 외에 등록된 클레임도,

공개 클레임도 아닌 email과 hello는 비공개 클레임 값이다.


서명은 해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도로 사용하며,

헤더의 인코딩 값과 내용의 인코딩값을 합친 후에 주어진 비밀키를 사용해 해시값을 생성한다.


토큰 유효기간

그런데 만약 토큰을 주고받는 환경이 보안에 취약해서 토큰 자체가 노출되면 어떻게 될까? 
이를 테면 구매한 영화 티켓의 정보가 노출되어서 다른 사람이 이 티켓으로 영화를 보려고 한다고 해보자. 

이럴 때 어떻게 해야 이 문제를 막을 수 있을까? 

 

토큰은 이미 발급되면 그 자체로 인증 수단이 되므로 

서버는 토큰과 함께 들어온 요청이 토큰을 탈취한 사람의 요청인지 확인할 수 없다.

 


리프레시 토큰이 있다면?
토큰의 유효기간이 하루라면 어떨까요? 하루 동안은 그 토큰으로 무엇이든 할 수 있을 테니 문제다. 

그러면 토큰의 유효기간이 짧으면 되지 않을까. 

 

그렇지만 토큰의 유효기간이 짧으면 사용자 입장에서는 받은 토큰을 너무 짧은 시간만 활용할 수 있으니 불편하다. 

이러한 불편한 지점을 해결하기 위해 리프레시 토큰이 등장한다. 

리프레시 토큰은 액세스 토큰과 별개의 토큰이다. 

사용자를 인증하기 위한 용도가 아닌 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급하기 위해 사용한다. 

액세스 토큰의 유효 기간은 짧게 설정하고,리프레시 토큰의 유효 기간은 길게 설정하면 
공격자가 액세스 토큰을 탈취해도 몇 분 뒤에는 사용할 수 없는 토큰이 되므로 더 안전하다!

[그림]

 

[설명]

클라이언트가 서버에게 인증을 요청한다.

서버는 클라이언트에서 전달한 정보를 바탕으로 인증 정보가 유효한지 확인한 뒤,

    액세스 토큰과 리프레시 토큰을 만들어 클라이언트에게 전달한다. 클라이언트는 전달받은 토큰을 저장한다.

서버에서 생성한 리프레시 토큰은 DB에도 저장해둔다.

 

인증을 필요로 하는 API를 호출할 때 클라이언트에서 저장된 액세스 토큰과 함께 API를 요청한다.

서버에서 전달받은 액세스 토큰이 유효한지 검사한 뒤에 유효하다면 클라이언트에서 요청한 내용을 처리하게 된다.

 

시간이 지나고 액세스 토큰이 만료된 뒤에 클라이언트에서 원하는 정보를 얻기 위해 서버에게 API 요청을 보낸다.

서버에서 액세스 토큰이 유효한지 검사하는데, 만료된 토큰이면 유효하지 않기 때문에

    토큰이 만료되었다는 에러를 전달한다.

 

클라이언트에서는 이 응답을 받고 저장해둔 리프레시 토큰과 함께 새로운 액세스 토큰을 발급하는 요청을 전송한다.

서버에서는 전달받은 리프레시 토큰이 유효한지,

    DB에서 리프레시 토큰을 조회한 후 저장해둔 리프레시 토큰과 같은지 확인하는 작업을 수행한다.

만약 유효한 리프레시 토큰이라면 새로운 액세스 토큰을 생성한 뒤 응답한다.

    그 이후에 클라이언트는 번과 같이 다시 API를 요청한다.

 

728x90
Comments