사용자가 서버에 접근할 떄 이 사용자가 괜춘한(인증된) 사용자인지 확인하는 방법은
대표적으로 서버 기반 인증
과 토큰 기반 인증
이 있다.
스프링 시큐리티에서는 기본적으로 세션 기반 인증 제공한다.
-> 사용자마다 사용자의 정보를 담은 세션 생성 & 저장하여 인증함
토큰 기반 인증은 말 그대로 토큰
사용
❓ 토큰
서버에서 클라이언트를 구분하기 위한 유일한 값
- 서버가 토큰을 생성해 클라이언트에게 제공
- 클라이언트는 이 토큰을 갖고 있다가 여러 요청을 토큰이랑 같이 넘김
- 서버는 토큰만 보고 유효한 사용자인지 검증
사용자 인증 정보가 담겨있는 토큰이 클라이언트에 있으므로 서버에 저장할 필요 없음
서버가 데이터를 유지하려면 그만큼 자원을 소비해야 함.
상태 관리를 할 필요가 없어서 완전한 무상태 (stateless) 로 효율적인 검증 가능
❓ 상태 관리
사용자의 인증 상태를 유지하면서 요청을 처리하는 것
무상태성은 확장성에 영향을 줌
오ㅐ❓ > 서버를 확장할 때 상태 관리를 신경 안 쓰니까 서버 확장도 쉽게 함
IF.
주문 서버
,결제 서버
IN 물건 파는 서비스
인증법 접근 세션 각각 API에서 인증 처리해야 함 토큰 하나의 토큰으로 결제 서버와 주문 서버에 요청을 보냄
토큰 방식은 HMAC (Hash-based Message AuthentiCation)
기법이라고도 함
토큰을 발급한 이후, 토큰 정보 변경하는 행위는 할 수 없음
즉, 토큰의 무결성이 보장..
하나라도 바꾸면 서버는 토큰이 유효하지 않다고 판단함
비밀키 (HMAC algorithm)
방식 또는 공개/개인키 (RSA, ECDSA)
방식으로 서명❓ JSON (JavaScript Object Notation)
데이터를 키-값(key-value)
쌍으로 구성하는 경량 데이터 형식
- 사람이 읽기 쉽고, 기계가 빠르게 파싱 가능
- 웹에서 데이터를 주고 받을 때 많이 사용됨
{ "name": "Alice", "age": 25, "isStudent": false, "skills": ["Java", "Spring Boot", "Vue.js"], "address": { "city": "Seoul", "country": "Korea" } }
JWT를 암호화 하면 기밀성을 포함 할 수 있음 = JWE (Json Web Encryption)
JWT (서명된 토큰) | JWE(암호화된 토큰) | |
---|---|---|
기능 | 무결성 검증 (변조 방지) | 기밀성 제공 (내용 숨김) |
Payload 노출 | 누구나 읽을 수 있음 | 암호화 되어 읽을 수 없음 |
보안성 | 변조 방지 | 변조 방지 + 데이터 보호 |
예시 | OAuth2, 인증 토큰 | 민감한 데이터 전송 |
.
을 기준으로 Header(헤더), Payload(내용), Signature(서명)으로 이루어짐
ex) xxxx.yyyy.zzzz
헤더는 일반적으로 '토큰 유형 & 사용되는 서명 알고리즘 ' 두 부분으로 구성됨.
{ // 예시
"alg": "HS256",
"typ": "JWT"
}
Header는 Base64Url로 인코딩 되어 JWT의 첫 번째 부분을 구성함
❓ Base64Url 인코딩
Base64 인코딩 의 변형된 형태
기존 Base64 인코딩은 URL에 사용 시 문제가 될 수 있는 문자를 포함 할 수 있어서 이른 URL에 적합하게 수정한 것
- 바이너리 데이터를 아스키 문자열로 변환하는 방법
- 주로 텍스트나 이미지 등의 데이터를 웹에서 안전하게 전송하기 위해 사용함
- 일반적으로 6비트씩 64개 문자 사용
토큰과 관련된 정보(Claim)를 담음
❓ Claim
엔티티와 추가적인 데이터에 대한 설명
Registerd(등록된), public (공개), private (비공개) claim으로 나뉨
토큰에 대한 정보를 담는 데 사용
JWT는 간결하게 작성 돼야 하므로 클레임 이름은 3글자로 제한
이름 | 설명 | 형식 |
---|---|---|
iss (Issuer) | 토큰 발급자 | |
sub (Subject) | 토큰 제목 | |
aud (Audience) | 토큰 대상자 | |
exp (Expriration) | 토큰 만료시간, 현재 시간 이후 설정 | Numeric Data |
nbf (Not before) | 토큰의 활성 날짜, 해당 날짜 전까지 토큰 처리 X | Numeric Data |
iat (Issued At) | 토큰이 발급된 시간 | Numeric Data |
jti (Jwt Id) | JWT의 고유 식별자 | 대소문자 구분 |
공개되어도 상관 없는 클레임
다른 시스템과의 상호운용성을 위해 사용될 수 있음
다른 시스템과의 충돌을 피하기 위해 유니크한 이름을 가져야 하며, 보통 URI로 작성
발급자와 수신자 간에만 의미 있는 클레임
다른 시스템과 공유되지 않으며, 해당 애플리케이션이나 서비스에서만 사용
JWT는 Header와 Payload를 Base64Url로 인코딩 하여 토큰 생성
디코딩이 정말 쉽기때문에, 민감한 정보는 넣지 말아야 함
해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도
Header 인코딩 값, Payload 인코딩 값 그리고 비밀키를 사용해 해시 값 생성
글이 길어지면 읽기 싫은 관계로 [Spring] 토큰 기반 인증, JWT 2편 에서 계속...