JWT이란?
JWT는 Json Web Token의 약자로, 웹에서 사용되는 JSON 형식의 토큰에 대한 웹 표준 규격이다. 주로 사용자의 인증, 인가 정보를 서버와 클라이언트 간에 안전하게 주고받기 위해 사용된다.
JWT의 특징
- 웹 표준을 따르고 있다.
- URL-safe 하다. (URL에서 사용할 수 있는 문자로만 이루어져 있다.)
- 필요한 모든 정보를 하나의 객체에 담아서 전달하기 때문에 JWT 하나로 인증을 마칠 수 있다
JWT 구조
JWT 토큰은 헤더(header)와 페이로드(payload), 서명(signature) 세 부분으로 나누어지고, 각 부분이 ' . '으로 구분된다.
헤더(header)
토큰의 유형과 서명 알고리즘이 명시된다.
{
"alg" : "HS256",
"typ" : "JWT"
}
페이로드(payload)
페이로드에는 claim이라고 불리는 사용자의 인증, 인가 정보가 담기게 된다.
이 claim에는 key - value 형태로 JWT에 저장하고자 하는 데이터를 넣을 수 있다.
JWT 토큰은 네트워크로 전송되어야 하기 때문에 공간을 적게 차지해야 유리하기 때문에, 특이하게 key를 3글자로 줄이는 관행이 있다고 한다.
{
"sub" : "userId",
"iat" : 1212431235
}
대표적으로 사용되는 JSON 키 이름으로는 sub(인증 주체), iat(발급 시간), exp(만료 시간) 등이 있다.
서명(signature)
서명 부분에 헤더와 페이로드가 비밀 키로 서명되어 저장되게 된다.
JWT의 사용
JWT 토큰을 이용하여 Spring security 로그인을 관리하는 방법을 알아보자.
우선 간단히 흐름을 정리해 보자.
- 사용자 로그인 시 JWT accessToken을 발행한다.
- 해당 accessToken을 클라이언트에서 관리하며, 모든 Http요청에서 Authorization Header에 accessToken을 포함시킨다.
- SpringSecurity config에서 필터를 등록해서 모든 요청 시 filter에서 JWT 토큰 자체에 문제에 없는지를 체크하고, 문제가 없다면 SpringSecurity Context에 UserDetail을 로드하는 방식으로 인증을 하게 된다.
일련의 과정을 SpringSecurity Config에서 등록하고, filter에서 확인 후 Controller 단에서 SpringSecurity Context의 유저 정보를 확인한다.
JWT의 장점과 한계
JWT의 장점
JWT의 등장 이전에는 웹에서 쿠키와 세션을 이용한 사용자 인증을 구현하는 경우가 많았다. 그러나 이제는 JWT를 이용하는 방식이 더 자주 사용되고 있다고 한다. 어떤 이유 때문에 JWT를 사용하게 되었을까?
가장 큰 이유는 JWT는 토큰 자체에 모든 사용자 정보가 저장되어 있기 때문에, 서버에서는 그 토큰을 검증하기만 하면 인증 절차가 완료된다.
반면에 쿠키와 세션을 이용하면 서버 단에 로그인한 모든 사용자의 세션을 DB나 캐시에 저장해 두고 쿠키로 넘어온 세션 ID로 사용자 데이터를 매번 조회해야만 한다.
이러한 이유 때문에 JWT를 사용하게 되면 이용자 수가 많아지더라도 추가 인프라 비용을 크게 절감할 수 있게 된다.
또한, 요즘에는 쿠키를 허용하지 않는 추세이기 때문에 더더욱 JWT가 권장된다.
JWT의 한계
JWT는 발행 시간과 만료시간을 설정할 수 있다. 그러나 특정 토큰을 무효화 할 수는 없다. 그래서, 토큰이 탈취 당했을 경우에 대처 방법을 따로 생각해봐야 한다.
또한, 탈취 당하지 않았더라도, 특정 기기에 대한 로그아웃을 JWT를 무효화시키는 방식으로 구현할 수 없게 된다.
따라서 AccessToken의 만료시간을 짧게 하고, RefreshToken을 도입하는 방식으로 해결하게 된다.
'JAVA & Spring > Spring Security' 카테고리의 다른 글
[Spring Security / JWT] Spring Security - JWT 토큰 인증/인가 (0) | 2024.01.12 |
---|---|
[Spring Security] 스프링 시큐리티 SecurityContext에 직접 Authentication(PrincipalDetails) 넣기 (0) | 2023.10.16 |
[Spring] 카카오 로그인 API 사용 방법 (17) | 2023.10.15 |