옛날에는 서버 기반 인증 방식을 사용하다가 시스템이 점점 많아지고 커짐에 따라 서버 기반 인증 방식의 한계가 나타났고, 토큰 기반 인증 방식이 등장하게 되었다. JWT 는 토큰 기반 인증 방식 중 하나인데 두 인증 방식의 차이부터 JWT 이론 및 실습까지 차근차근 알아보자.
이건 TMI 인데 .. 진짜 처음에 JWT 에 대한 인식 없었을 때 JWT 에 대해서 들었을 때 java 에서만 사용하는 토큰 인 줄 알았다 😰
HTTP 는 다음과 같이 2가지의 특징을 가지고 있는데
이름 | 설명 |
---|---|
Connenctionless | 클라이언트가 요청을 서버에게 보내면 서버는 이에 대한 적절한 응답을 한 후에 연결을 종료합니다. |
Stateless | Connenctionless의 특징으로 서버와 클라이언트와의 연결이 종료된다면 상태 정보는 저장하지 않고 사라집니다. |
위 특징을 가지고 있기 때문에 로그인 후 사용자가 새로운 요청을 했을 때 과거에 로그인 한 사실을 기억하지 못한다
👉 그렇기 때문에 어딘가에 사용자가 로그인 했다는 걸 저장하고 있어야 한다.
서버를 기반으로 인증하는 방식이다.
그렇기 때문에 서버 측에서 사용자들의 정보를 기억하고 있어야 한다.
서버 기반 인증 방식은 서버 측에서 유저 정보를 세션을 통해 저장한다.
서버(세션) 기반 인증 방식은 아래와 같은 과정을 가진다.
출처 : https://velopert.com/2350#google_vignette
즉, 유저의 정보는 서버에 저장되어 있고,
유저가 요청을 했을 때 서버에 있는 사용자 정보로 유효한 사용자인지 확인하고 맞는 경우 응답을 한다.
하지만 서버 인증 방식에는 몇가지의 단점이 있다.
① 사용자 수가 늘어날수록 세션으로 저장하는 정보가 증가하기 때문에 메모리를 많이 사용하게 된다
② 세션을 관리할 때 많이 사용하는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하기 때문에 여러 도메인에서 관리가 번거롭다
이러한 문제점을 해결하기 위해 토큰 기반 인증 방식이 나오게 되었다
인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내서 유효성을 검사한다.
서버측에서 사용자에 대한 정보를 가지고 있지 않고 클라이언트에서 오는 요청 만으로 인증을 진행한다
출처 : https://velopert.com/2350#google_vignette
서버에서 사용자에 대한 정보를 가지고 있지 않고, 사용자가 토큰을 가지고 요청을 하는 방식이다
① 무상태성 (Stateless)
: 토큰 기반 인증 방식에서 사용되는 토큰은 서버가 아니라 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless 하다.
② 확장성 (Scalability)
: 클라이언트와 서버의 연결 고리가 없기 때문에 확장성이 매우 용이하다.
EX) 토큰 기반 인증 방식이 아니라 서버 기반 인증 방식인 경우 서버를 확장하여 분산처리를 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정해주야 하지만 토큰 기반 인증 방식은 토큰만 있으면 되기 때문에 상관 없다.
③ 보안성
: 클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라진다
④ 여러 플랫폼 및 도메인
: 서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.
① 보안
: 토큰이 노출될 경우 유효기간이 지나기 전까지는 토큰을 사용할 수 있다. 이를 해결하기 위해 유효기간을 짧게 잡고 갱신할 수 있도록 해야한다.
토큰 기반 방식의 장점 중 하나인 무상태성에서 stateless 라는 말이 잠깐 나왔는데, stateless 란 뭘까 ?
stateless vs stateful
상태를 서버에서 저장하는지 안하는지 여부에 따라 나눠진다
stateless (무상태)
서버에서 브라우저의 상태(쿠키 or 세션)를 저장하지 않는 형태
토큰 기반 인증 방식이 여기에 속한다.
EX) TCPstateful (상태 유지)
서버에서 브라우저의 상태(쿠키 or 세션)를 저장하는 형태
서버 기반 인증 방식이 여기에 속한다.
EX) UDP / HTTP
그러면 이제 본격적으로 JWT 에 대해서 알아보도록 하자
JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주기 위한 토큰
위에서 설명한 서버 기반 인증 방식과 토큰 기반 인증 방식 중 토큰 기반 인증 방식에 속한다.
공식 사이트 👉 https://jwt.io/
.
을 구분자로 3가지 문자열로 구성되어 있다
jwt 토큰은 위에 명시되어 있는 공식 사이트에서 복호화 해볼 수 있다. 아래는 공식 사이트에 공개되어 있는 JWT 예시이다.
Signature 를 해싱하기 위한 알고리즘 정보
typ : 토큰의 타입을 지정
alg : 해싱 알고리즘 지정 , 토큰을 검증 할 때 사용되는 signature 부분에서 사용한다.
서버와 클라이언트가 주고받는 , 시스템에서 실제로 사용될 정보에 대한 내용
조각
을 클레임 (claim) 이라고 부르고 name / value 로 이루어져 있다 등록된 클레임
이름 | 설명 |
---|---|
iss | 토큰 발급자 |
sub | 토큰 제목 |
aud | 토큰 대상자 |
exp | 토큰 만료 시간 |
nbf | 토큰의 활성 날짜 |
iat | 토큰이 발급된 시간 |
jti | JWT 의 고유 식별자 , 중복 처리를 방지하기 위하여 사용 |
공개 클레임
"https://soyeon.com/jwt_claims/is_admin": true
비공개 클레임
username: "soyeon"
2개의 등록된 클레임 + 1개의 공개 클레임 + 2개의 비공개 클레임으로 구성된 예시
{
"iss": "naver.com",
"exp": "1485270000000",
"http://naver.com/jwt_claims/is_admin": true,
"userId": "12",
"username": "soyeon"
}
토큰의 유효성 검증을 위한 문자열
생성된 토큰은 HTTP 통신 할 때 header 에 Authorization value 로 값을 넘겨주면 사용할 수 있다
{
"Authorization": "Bearer {생성된 토큰 값}",
}
Access Token
Refresh Token
Access Token | Refresh Token | 결과 |
---|---|---|
유효 | 유효 | 인증 완료, 요청한 정보 리턴 |
유효 | 만료 | Refresh Token 재발급 |
만료 | 유효 | Access Token 재발급 |
만료 | 만료 | 권한 없음 |
[Server] 토큰 기반 인증 VS 서버(세션) 기반 인증
JWT란?
[Server] JWT(Json Web Token)란?
JWT란?