Spring Security를 사용하여 웹 상에서의 인증/인가 작업을 구현할 때는 세션-쿠키 기반의 인증 방식을 사용한다.
하지만 이러한 인증 방식에는 몇가지 단점이 존재한다.
이러한 단점을 보완하는 인증 방식으로 JWT 인증 방식이 존재한다.
이때 JWT가 어떻게 사용되고 왜 필요한지 한번 살펴보자
✨ JWT의 개념과 필요성
세션-쿠키 기반 인증 방식의 한계
- 세션-쿠키 기반 인증 방식에서는 클라이언트의 세션 정보를 서버의 DB에 저장한다.
- 이 경우 클라이언트의 매 요청마다 DB를 참조해야 하므로 인증 과정이 길어진다.
- 서비스가 확장되어 클라이언트의 수가 많아질 경우, 그만큼 서버에 저장되는 세션 정보도 많아짐으로 서버의 부담도 증가한다.
- 세션-쿠키 인증 방식의 경우, 클라이언트는 발급받은 토큰 아이디를 쿠키에 저장한다.
- 일반적으로 이런 쿠키 시스템은 웹브라우저에서만 지원한다.
- 때문에 모바일 네이티브 앱 등을 사용해 인증을 받을 경우, 세션 아이디를 저장하고 전송하는 과정을 직접 구현해야하기 때문에 번거롭다.
JWT를 사용한다면 위와 같은 문제를 해결 할 수 있다.
JWT란?
JWT(Json Web Token)는 클라이언트-서버간의 인증/인가를 처리할 때 토큰을 이용하여 인증/인가를 처리하는 방식이다.
이때 사용되는 토큰을 Json Web Token이라고 한다.
JWT의 장점은 아래와 같다.
- 서버는 요청에 대한 권한 인증을 토큰을 통하여 처리하므로, DB를 참조할 필요가 없다.
- 마찬가지로 토큰을 사용하기 때문에, DB에 세션 정보를 따로 저장하지 않아도 된다.
- 인증에 사용되는 토큰은 다양한 방식으로 전송 가능하기 때문에, 다양한 플랫폼에서도 유연하게 동작한다.
✨ JWT의 구조
jwt는 헤더(Header)
, 정보(Payload)
, 서명(Signature)
으로 이루어져있다.
이때 각 부분은 Base64
방식으로 인코딩되며, 각 부분은 .
으로 구분된다.
- 헤더(Header): jwt가 암호화되는 방법을 저장한다.
- 서버는 jwt의 유효성을 검사할 때,
암호화된 서명(Signature)
을비밀키
와헤더에 저장된 방법(Alg)
으로 해독 하여 유효성을 검사한다.
- 서버는 jwt의 유효성을 검사할 때,
- 정보(Payload): 실제로 서버에 전달될 정보를 담는다.
- 각 정보는
키(Key)
:값(Value)
형태로 저장된다.- 이때 저장되는 정보 하나 하나를 클레임(Claims)이라고 한다.
- 클레임의 종류는 아래와 같다.
- 등록된(Registered) 클래임
- 공개(Public) 클래임
- 비공개(Private) 클래임
- 페이로드는 서버가 각 클라이언트를 식별할 수 있는 정보(id, email 등)를 포함해야한다.
- 페이로드에는 민감한 정보(password 등)을 포함시키지 않는 것이 좋다.
- 각 정보는
- 서명(Signature): 전달받은 JWT가 유효한지 검증하기 위해 사용한다.
- 이때 서명은 위의 헤더와 페이로드를
Base64
로 인코딩한 값과, 비밀키를 가지고, 헤더에 정의된 암호화 알고리즘으로 암호화 시킨 값이다.- 이렇게 암호화된 값은 이후 서버에서 비밀키를 가지고 다시 해석할 수 있다.
- 이때 서명은 위의 헤더와 페이로드를
JWT는 위와 같은 부분들로 이루어져있으며, 각 부분은 .
으로 구분된다.
jwt.io에서 간편하게 jwt를 생성해볼수 있으며, 생성된 JWT의 예시는 아래와 같다.
✨ JWT의 동작 방식
JWT를 사용한 인증 과정은 다음과 같다.
- 클라이언트가 처음 로그인, 인증을 위해
id
와pw
를 서버에 전송한다. - 서버는 db를 조회하여 해당 정보가 유효한지 검증한다.
- 만약 해당 정보가 유효하면,
해당 유저의 정보
와서버만 알고있는 비밀키
를 가지고 JWT 를 생성한다. - 서버는 생성된 토큰을 클라이언트에게 전달하고, 클라이언트는 해당 토큰을 저장한다.
- 클라이언트는 이후 서버에 요청을 보낼 때 마다 해당 토큰을 함께 전송한다.
- 서버는 전달받은 토큰이 유효한지 검증한다.
- 이때 검증할때는 서명 값을 사용하여 검증한다. 검증 과정은 아래와 같다.
- 토큰의 헤더에 저장된
암호화 알고리즘
을 참조함 - 토큰의
서명값
을, 위의암호화 알고리즘
과비밀키
를 사용하여 해석 - 해석된 서명값이 유효한지 검증
- 토큰의 헤더에 저장된
- 이때 검증할때는 서명 값을 사용하여 검증한다. 검증 과정은 아래와 같다.
- 만약 해당 토큰이 유효한 토큰이면, 서버는 요청에 알맞은 응답을 한다.
✨ JWT의 단점
JWT가 다양한 장점을 가진것은 맞지만, 그렇다고 만능인 것도 아니다.
JWT의 한계는 아래와 같다.
- 이전에 발급한 토큰에 대한 제어를 할 수 없다.
- 기존 세션 인증 방식에서는, 서버 DB에 저장된 세션 정보를 처리하면 되었지만, JWT에서는 불가능하다.
- 이러한 문제를 위해 토큰의 유효기간을 짧게 설정하는 등의 방법을 사용한다.
- 토큰이 탈취될 경우 사용자의 정보가 그대로 유출된다.
- JWT에는 사용자의 정보가 암호화되지 않고 그대로 들어있다.
- 이 때문에 JWT를 생성할 때 비밀번호와 같은 민감한 정보는 포함시키지 않는 것이 좋다.
이처럼 JWT와 세션 방식은 서로 각각의 장점을 가지고 있기 때문에, 각 상황에 맞게 알맞은 인증 방식을 사용하는 것이 좋다.
'Back End > Spring && Spring Boot' 카테고리의 다른 글
[Spring boot / h2] Embedded VS In-Memory VS Server (0) | 2024.06.26 |
---|---|
[Spring boot / JPA] 스프링 부트 데이터베이스 초기화 (0) | 2024.06.26 |
[Spring Security] 현재 로그인된 유저 정보 얻기 - @AuthenticationPrincipal (0) | 2024.06.18 |
[JPA] Entity 생성 시간 자동 기록하기 (1) | 2024.06.15 |
[Spring Boot/Jpa] DB에 반영되지 않는 Entity 필드 정의하기 (0) | 2024.06.15 |