[Springboot] JWT 정리

JWT란

• JSON Web Token (JWT)은 정보를 안전하게 전송하기 위한 간결하고 자체 포함된 방법을 정의하는 오픈 표준(RFC 7519)으로, 이는 JSON 객체로 정보를 전송하는 데 사용됩니다.

• JWT 또는 JSON Web Tokens (RFC 7519)은 주로 REST API를 보안하는 데 사용되는 표준입니다.

• JWT는 클라이언트와 서버 간에 안전하게 통신하는 가장 좋은 방법입니다.

• JWT는 상태가 없는 인증 메커니즘을 따릅니다.

JWT를 사용해야 하는 경우

• 인가 (Authorization): JWT는 주로 인가 목적으로 사용됩니다. 사용자의 권한과 역할에 관한 정보를 안전하게 전달하여 클라이언트가 특정 자원에 액세스하거나 특정 작업을 수행하는 데 필요한 자격 증명을 가지고 있는지 확인합니다.

• 정보 교환 (Information Exchange): JWT는 정보를 안전하게 전달하는 간결하고 자체 포함된 방법을 제공합니다. 특히 웹 애플리케이션, API 및 마이크로서비스의 맥락에서 시스템 간에 정보를 안전하게 교환하는 데 유용합니다. 토큰은 필요한 데이터를 포함하고, 전송 중에 정보가 조작되지 않았음을 확인하기 위해 무결성을 검증할 수 있습니다.

JSON Web Token (JWT) 구성 요소

JSON Web Token (JWT)은 세 가지 부분으로 구성됩니다: 헤더(header), 페이로드(payload), 그리고 시그니처(signature). 이러한 세 부분은 점(.)으로 구분되어 토큰의 구조를 이룹니다.

image

헤더 (Header):

헤더에는 일반적으로 두 가지 부분이 있습니다: 토큰의 유형인 JWT와 사용 중인 서명 알고리즘인 HMAC SHA256 또는 RSA와 같은 정보가 포함됩니다. 헤더는 Base64Url로 인코딩되어 JWT의 첫 번째 부분을 형성합니다.

예시 헤더:

{
  "alg": "HS256",
  "typ": "JWT"
}

페이로드 (Payload):

페이로드에는 클레임(claims)이 포함됩니다. 클레임은 엔터티(일반적으로 사용자)에 대한 진술과 추가 데이터입니다. 등록된 클레임, 공개 클레임, 그리고 비공개 클레임의 세 가지 유형이 있습니다. 페이로드도 Base64Url로 인코딩됩니다. 예시 페이로드:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

시그니처 (Signature):

시그니처는 인코딩된 헤더, 인코딩된 페이로드, 비밀 키 및 지정된 알고리즘을 사용하여 생성됩니다. 이 시그니처는 JWT의 송신자가 자신이 말하는 대로이며 메시지가 중간에 변경되지 않았음을 확인하는 데 사용됩니다. 예시 시그니처 (HMAC SHA256 사용):

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

최종 JWT는 Base64Url로 인코딩된 헤더, 페이로드 및 시그니처가 점으로 구분된 것입니다:

base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + signature

이러한 구조는 JWT를 간결하고 URL에 안전하며 웹 환경에서 간편하게 전달할 수 있도록 합니다.

JWT의 작동 방식

image

1 . 인가 (Authentication):

사용자가 로그인하면 서버는 해당 사용자에 대한 클레임(claims)을 생성합니다. 이 클레임은 사용자의 ID, 역할, 권한 등과 같은 정보를 포함합니다. 이 클레임 정보는 토큰의 페이로드 부분에 저장됩니다.


2 . 토큰 발급 (Token Issuance):

서버는 헤더, 페이로드, 시그니처를 포함한 JWT를 생성합니다. 헤더는 토큰의 유형과 서명 알고리즘을 지정하고, 페이로드는 클레임 정보를 담고 있습니다. 시그니처는 헤더와 페이로드를 서명하여 토큰의 무결성을 보장합니다.


3 . 토큰 전달 (Token Transmission):

클라이언트는 로그인 후 서버로부터 받은 JWT를 안전하게 보관합니다. 이 토큰은 일반적으로 HTTP 헤더나 쿠키 등을 통해 서버에 전달됩니다.


4 . 요청과 검증 (Request and Verification):

클라이언트가 서버에 요청을 보낼 때, JWT는 헤더, 페이로드, 시그니처로 분리되어 전달됩니다. 서버는 헤더와 페이로드를 사용자의 클레임을 확인하기 위해 해독하고, 시그니처를 사용하여 토큰의 무결성을 검증합니다.


5 . 인가 처리 (Authorization Handling):

서버는 클라이언트의 요청에 대한 권한 검사를 수행하고, 클라이언트가 요청한 작업을 수행할 수 있는지 확인합니다. 만약 토큰이 유효하고 권한이 부여된 경우, 서버는 요청을 처리하고 클라이언트에게 응답합니다.


6 . 토큰 갱신 (Token Refresh):

토큰의 수명이 만료되면 클라이언트는 새로운 토큰을 요청하여 갱신할 수 있습니다. 이때, 서버는 새로운 토큰을 발급하고 이전 토큰은 폐기합니다. JSON Web Tokens는 이러한 방식으로 작동하여 안전하게 정보를 전송하고, 클라이언트와 서버 간에 인증 및 권한 부여를 수행합니다.



기존 인증방식과의 차이(스프링 시큐리티에서 jwt 사용 vs 미사용)

image

기본 인증의 경우, 하드 코딩된 사용자 이름과 비밀번호를 헤더에 전달해야 함. 각각의 API 헤더의 이름과 비밀번호를 전달해야한다. 이게 기본 인증의 단점이다.


시큐리티에서 jwt 사용시

image

사용자의 이름과 비밀번호 일치 시 jwt 토큰 생성 후 전송함. 클라이언트에 대한 로그인 API 응답의 일부로 클라이언트는 jwt 토큰을 헤더에 전달함

단순하게 가장 큰 차이는 직접적으로 이름과 비밀번호를 전달하냐, jwt로 토큰을 전달하냐의 차이

일반적인 jwt 개발 과정

단계 1: JWT 종속성 추가 단계 2: JwtAuthenticationEntryPoint 생성 단계 3: application.properties 파일에 jwt 속성 추가 단계 4: JwtTokenProvider 생성 단계 5: JwtAuthenticationFilter 생성 단계 6: JWTAuthResponse DTO 생성 단계 7: Spring Security 구성에서 JWT 구성 단계 8: 로그인/ signin API를 클라이언트에 토큰 반환하도록 변경





© 2021.03. by yacho

Powered by github