스프링 시큐리티와 JWT를 결합하여 웹 애플리케이션의 보안을 강화하는 방법에 대해 알아보자.
스프링 시큐리티는 강력한 인증(Authentication)과 인가(Authorization) 기능을 제공하여 개발자가 보다 안전한 애플리케이션을 구축할 수 있도록 도와준다.
JWT는 Json Web Token의 약자로, 클라이언트(사용자)와 서버 간에 정보를 JSON 개체로 안전하게 전송하기 위한 개방형 표준(RFC 7519)이다.
웹 상에서 정보를 JSON 형태로 주고받기 위해 표준 규약에 따라 생성된 암호화된 토큰으로, 복잡하고 읽을 수 없는 문자열 형태로 저장된다.
RESTful API와 같은 환경에서 인증 정보를 안전하게 전송하는 데 유용하다.
JWT 는 헤더(HEADER), 페이로드(PAYLOAD), 시그니처(SIGNATURE) 로 구성되어 있다.

어떤 알고리즘으로 암호화 할 것인지, 어떤 토큰을 사용할 것 인지에 대한 정보가 들어있다.
alg : Signature를 만드는데 사용한 알고리즘 정보typ : Token의 타입실질적으로 전달해야 할 정보들을 담고 있다. 이 정보들을 Claim이라고 한다.
sub : Registered Claims로 토큰 주제를 의미한다.name : Public Claims로 충돌 방지 네임 스페이스를 사용하여 정의한다.iat : Registered Claims로 토큰 발급 시간을 의미한다.HEADER와 PAYLOAD의 무결성을 확인한다.
base64UrlEncode(header) + "." + base64UrlEncode(payload) : Base64 URL 인코딩 방식으로 인코딩 되어 있다. 이 두 부분을 인코딩된 형태로 결합한다.HMACSHA256 : SIGNATURE 생성에 사용된 알고리즘your-256-bit-secret : SIGNATURE를 생성할 때 사용된 비밀 키. 이 키는 토큰을 발급한 서버에만 알려져 있어야 하며, 서버는 이 비밀 키를 사용하여 클라이언트가 제출한 JWT의 서명을 검증한다.단일 토큰의 사용처를 추적하면 아래와 같다.
권한이 필요한 요청은 회원 서비스나 주문 서비스 등에서 자주 발생한다. JWT는 많은 요청을 처리하기 위해 클라이언트 사이드에서 HTTP 통신을 통해 서버로 전송된다.
그러나 이로 인해 해커가 클라이언트 측에서 XSS 공격을 이용하거나 HTTP 요청을 가로채어 토큰을 탈취할 수 있다. 이에 대비하여 여러 보안 기술을 사용하여 토큰 탈취를 방지하고, 탈취된 경우에도 대응할 수 있어야 한다.
단일 토큰 사용 시 발생할 수 있는 문제를 해결하기 위해 Access 토큰과 Refresh 토큰을 사용할 수 있다.
Access 토큰
자주 사용되며, 권한이 필요한 모든 요청에 사용되는 짧은 생명 주기의 JWT로 약 10분 정도 유지된다.
Refresh 토큰
Access 토큰이 만료되었을 때 재발급 받기 위해 사용되며, 긴 생명 주기를 가진다. 보통 24시간 이상 유지된다.
Access 토큰의 짧은 생명 주기로 인해 자주 로그인을 요구하는 번거로움을 피하기 위해, Refresh 토큰을 사용하여 Access 토큰을 갱신한다.
사용 빈도가 적긴 하지만 Refresh 토큰도 탈취될 가능성이 있기 때문에 보호 방법이 필요하다.
Refresh Rotate
Access 토큰을 갱신할 때마다 새로운 Refresh 토큰을 발급하여 한 번 사용한 Refresh 토큰은 재사용하지 않도록 합니다.
Access 토큰
생명 주기가 짧지만 CSRF 공격은 클릭 한 번으로 요청을 전송할 수 있기 때문에 주로 로컬 스토리지에 저장된다.
Refresh 토큰
주로 쿠키에 저장됩니다. 쿠키는 XSS 공격을 받을 수 있지만, HttpOnly 속성을 설정하여 JavaScript로부터 접근을 제한할 수 있다.
만약 JWT가 탈취된 경우 서버는 주도권을 가지지 않기 때문에 생명 주기가 끝나기를 기다리는 것 외에 방어할 수 있는 방법은 없다.
생명 주기가 긴 Refresh 토큰
발급 시 서버 측 저장소에도 저장하여 요청이 들어올 때마다 저장소에서 존재 여부를 확인하여 주도권을 유지한다.
로그아웃 시 또는 탈취된 경우 서버 측 저장소에서 해당 JWT를 삭제하여 피해를 방지할 수 있다.