JWT란 ?
인증방식
서버 기반 인증 방식
- 서버 기반 인증 방식은 서버측에서 유저 정보를 저장 => 세션
- 유저가 로그인을 하면 세션을 만들고 서버의 메모리와 데이터베이스에 저장 문제
- 사용자 수가 늘어날수록 세션으로 저장하는 정보가 증가하기에 메모리를 많이 사용
- 쿠키는 단일 도메인 및 서브 도메인에서만 작동하기 때문에 여러 도메인에서 관리가 번거롭다
- 웹 어플리케이션에서 세션을 관리 할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있음, 여러 도메인에서 관리가 번거롭다 (CORS)
토큰 기반 인증 방식
- 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사
장점
- 무상태성(Stateless) & 확장성(Scalability) 토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.
stateless vs stateful
- 상태를 서버에서 저장하고 있다는 의미
- stateless : 서버에서 상태 저장 X
-
stateful : 서버에서 상태 저장
-
보안성 클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.
-
확장성(Extensibility) 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.
- 여러 플랫폼 및 도메인 서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.
JWT 가 필요한 이유
JWT = 토큰 기반 인증 방식
HTTP 는
- Connenctionless : 클라이언트가 요청을 서버에게 보내면 서버는 이에 대한 적절한 응답을 한 후에 연결을 종료합니다.
- Stateless : Connenctionless의 특징으로 서버와 클라이언트와의 연결이 종료된다면 상태 정보는 저장하지 않고 사라집니다.
위 특징을 가지고 있기 때문에 로그인 후 사용자가 새로운 요청을 했을 때 과거에 로그인 한 사실을 기억하지 못한다
=> 로그인 시 사용자에 따른 토큰을 가지고 있고 구입을 하거나 사이트를 이용할 때 이 토큰을 함께 요청 ,
토큰엔 요청한 사람의 정보가 담겨있기 때문에 DB를 조회하지 않고 누가 요청하는지 알 수 있다
JWT (Json Web Token) 란 ?
https://jwt.io/ JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주기 위한 토큰
JWT 구성
.
을 구분자로 3가지 문자열로 구성되어 있음
- 해싱 알고리즘 : alg
- 토큰 제목 : admin
- exp : 토큰 만료 시간
Header : Signature 를 해싱하기 위한 알고리즘 정보
- type : 토큰의 타입을 지정
- alg : 해싱 알고리즘 지정 , 토큰을 검증 할 때 사용되는 signature 부분에서 사용
Payload : 서버와 클라이언트가 주고받는 , 시스템에서 실제로 사용될 정보에 대한 내용
- 토큰에 담을 정보
- 여기에 담는 정보의 한
조각
을 클레임 (claim) 이라고 부르고 name / value 로 이루어져 있음 - 토큰에는 여러 클레임을 담을 수 있다
클레임이란 ?
등록된 클레임
- 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위하여 이름이 이미 정해진 클레임
- 사용은 모두 선택적
이름 | 설명 |
---|---|
iss | 토큰 발급자 |
sub | 토큰 제목 |
aud | 토큰 대상자 |
exp | 토큰 만료 시간 |
nbf | 토큰의 활성 날짜 |
iat | 토큰이 발급된 시간 |
jti | JWT 의 고유 식별자 , 중복 처리를 방지하기 위하여 사용 |
공개 클레임
- 충돌이 방지된 이름을 가져야 함 , 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 지음
"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"
}
Signature : 토큰의 유효성 검증을 위한 문자열
- 위 토큰이 유효한지 유효하지 않은지에 대한 정보를 가짐
- 암호화에 사용되는 키 값은 서버에 저장해 놓음
- 헤더의 인코딩 값과 정보의 인코딩값을 합친 후 주어진 비밀키로 해쉬를 하여 생성
사용방법
- 생성된 토큰은 HTTP 통신 할 때 Authorization value 로 저장
{ "Authorization": "Bearer {생성된 토큰 값}", }
장점 vs 단점
장점
- 중앙의 인증서버, 데이터 스토어에 대한 의존성 없음 , 시스템 수평 확장 유리
- Base64 URL Safe Encoding > URL, Cookie, Header 모두 사용 가능
단점
- Payload 의 정보가 많아지면 네트워크 사용량 증가, 데이터 설계 고려 필요
- 토큰이 클라이언트에 저장, 서버에서 클라이언트의 토큰을 조작할 수 없음