토큰 기반 인증 시스템
- 웹 보안의 바탕은, 인증(Authenticate) + 인가(Authorize) 로 구성된다.
1) 인증(Authenticate) : 요청 사용자 식별
2) 인가(Authorize) : 인증된 사용자가 보호된 리소스에 접근할 권한이 있는지 확인
- 토큰 기반 인증 시스템은,
인증을 받은 사용자에게 토큰을 발급하고
-> 사용자가 서버에 요청할 때 헤더(Header)에 발급 받은 토큰을 함께 보내도록 하여 유효성을 검사한다.
- 토큰 기반 인증 시스템은 서버 기반 인증 시스템과 달리, 클라이언트의 요청 시 클라이언트의 헤더에 담긴 토큰만으로 인증 정보를 확인 가능하고, 세션 관리 필요가 없어 서버 자원을 아낄 수 있다.
이런, 토큰 기반 인증 시스템에 사용되는 JWT에 대해 정리한다.
(토큰 기반 인증 시스템과 서버 기반 인증 시스템의 차이에 대한 내용도 정리 예정.)
JWT(JSON Web Token)이란,
1. JWT(JSON Wen Token)의 정의
- 사용자에 대한 속성 정보를 JSON 데이터 구조로 표현한 토큰
- 토큰의 기본 정보, 전달할 정보, 검증되었다는 시그니처 정보를 지님
- 자가 수용적(Self-Contained) 특징: 필요한 모든 정보를 자체적으로 지니고 있음
-> 토큰 자체를 정보로 사용하여 정보 전달
2. JWT의 구조
- Header(헤더), Payload(페이로드), Signature(서명) 세 부분을 ' . ' (구분자)으로 구분
- JSON 형태인 각 부분은 Base64로 인코딩 되어 표현
-> Base64 : 암호화된 문자열 X -> 같은 문자열에 대해 항상 같은 인코딩 문자열 반환
Ex) aaaa . bbbb . cccc
헤더 내용 서명
(1) Header(헤더)
- [alg]와 [typ]의 두 가지 정보로 구성
1) alg : Signature를 해싱하기 위한 알고리즘 지정 -> 토큰 검증 시 사용되는 Signature 부분에서 사용
Ex) HS256(SHA256) or RSA
2) typ : 토큰의 타입을 지정
Ex) JWT
{
"alg": "HS256",
"typ": JWT
}
(2) Payload(페이로드)
- 토큰에 담을 정보 존재
- 정보의 한 '조각' = 클레임(Claim) -> Json(Ket/Value) 형태의 한 쌍으로 이루어져 있다.
-> 토큰에는 여러 개의 클레임을 넣을 수 있다.
[클레임의 종류]
1) 등록된(Registered) 클레임
- 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터
- 서비스에 필요한 정보 X -> ' 토큰에 대한 정보 ' 들을 담기 위한 클레임
- 선택적으로 작성 가능 및 사용 권장
- Key의 String 길이는 3
- subject는 Unique한 값 -> 사용자 이메일 사용
[등록된 클레임 종류]
- iss(issuer) : 토큰 발급자
Key | Value |
iss(issuer) | 토큰 발급자 |
sub(subject) | 토큰 제목 |
aud(audience) | 토큰 대상자 |
exp(expiration) | 토큰 만료 시간 - 항상 현재 시간 이후로 설정 -> NumericDate 형식 Ex) 1480849147370 |
nbf(not before) | 토큰 활성 날짜 - 해당 날짜 전의 토큰은 비활성화 상태 |
iat(issued at) | 토큰 발급 시간 - 토큰 발급 이후 경과 시간(토큰의 age) |
jti(JWT ID) | JWT 토큰 식별자 - 중복 방지 및 일회용 토큰(Access Token) 등에 사용 |
2) 공개(Public) 클레임
- 사용자 정의 클레임
- 공개용 정보를 위해 사용
- 충돌 방지를 위한 이름으로 URI 포멧 사용
{
"https://simmigyeong.tistory.com/": true
}
3) 비공개(Private) 클레임
- 사용자 정의 클레임
- 서버와 클라이언트 사이에 임의로 지정한(필요한) 정보 저장
- 공개 클레임과 달리, 중복 시 충돌 가능성이 있어 사용 시 유의해야 한다.
{
"token_type": access
}
(3) Signature(시그니처)
- 서명은 토큰을 '인코딩' 하거나, '유효성을 검증' 할 때 사용하는 고유한 암호화 코드(서버만 알고 있음.)
- 헤더(Header)와 페이로드(Payload)의 값을 각각 [BASE64로 인코딩]하고,
-> 인코딩한 값을 [비밀 키]를 이용해, 헤더에서 정의한 알고리즘으로 [해싱]을 하고
-> 이 값을 다시[ BASE64로 인코딩]하여 생성한다.
HEADER | PAYLOAD | VERIFY SIGNATURE |
{ "alg": "HS256", "typ": "JWT" } |
{ "sub": "1234567890", "name": "Sim", "iat": 1516239022 } |
HMACSHA256( base64UrlEncode(header) + " . " + base64UrlEncode(payload) ) 한 값을 Base64 인코딩 |
헤더와 페이로드, 서명에 해당하는 내용이 각각 인코딩되어 JWT로 나타나는 결과값은 아래와 같다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNpbSIsImlhdCI6MTUxNjIzOTAyMn0.1MjAckWhJVC91zNAL9lfbT0TU-5eUNKUKFujNLABmPA
JWT(JSON Web Token)은 언제 사용하는가
1. 로그인
- 클라이언트가 아이디 + 패스워드로 로그인 요청
-> 서버가 아이디 + 패스워드 일치 여부 확인 -> 유효한 경우에, 토큰(JWT) 발급
-> 클라이언트가 다음에 어떠한 요청을 할 때, 발급받은 인증 토큰을 '헤더'에 포함시켜 요청
-> 서버에 요청이 오면, 헤더에 포함된 인증 토큰을 해석해 권한(인가) 확인
2. 정보교류
- 두 개체 사이에서 안정성 있는 정보 교환이 가능하다.
- 정보가 내장되어 있어, 정보를 보낸이가 바꾸거나 조작하지 않았는지에 대한 사실을 검증 가능하다.
JWT(JSON Web Token)의 장단점
1. 장점
- 사용자 인증에 필요한 모든 정보가 토큰 자체에 포함 -> 별도의 인증 저장소가 필요없음.
- 쿠키 전달 필요 X -> 쿠키 사용으로 발생하는 문제 방지 가능
- 트래픽에 대한 부담이 낮음.
- REST 서비스로 제공 가능
- 독립된 JWT
2. 단점
1) 데이터 증가에 따른 네트워크 부하
- 모든 요청에 대해 토큰 전송 -> 토큰에 담기는 정보가 많아질수록 네트워크 부하 증가
2) Self-Contained
- 토큰 자체에 모든 정보를 담고 있어, 토큰 만료 전 JWT가 탈취당하면, 서버에서 할 수 있는 것이 없다. -> 중요한 데이터를 payload에 넣어서는 안 된다.
3) 무상태성(stateless)
- JWT는 상태 저장 X(연결 유지 X) -> 최초 생성 후 임의 삭제 불가 -> 만료 시간 필수 지정
참고
- https://gorokke.tistory.com/181
- https://mangkyu.tistory.com/56
- https://wildeveloperetrain.tistory.com/20
'Web > Concept' 카테고리의 다른 글
[Web] JWT(JSON Web Token) (0) | 2022.05.22 |
---|---|
[Web] 서버 기반 인증 시스템과 토큰 기반 인증 시스템 (0) | 2022.05.22 |
[Web] Authentication & Autorization (0) | 2022.05.22 |
[Web] 쿠키(Cookie) & 세션(Session) (0) | 2022.05.22 |