JWT vs Session
목차
1.JWT는 무엇인가?
2.JWT와Session의 차이점
1.JWT는 무엇인가?
jwt는 json web token의 약자로써 웹에서 정보를 안전하게 전송하기 위한 토큰 기반의 인증 방식 중 하나로 jwt는 json을 활용해서 사용자의 정보를 일부 담습니다.
jwt의 구조는 header. payload. verify signature 로 이렇게 3가지로 구성이 되어있고 하나씩 설명을 해보도록 하겠습니다.
1-1.헤더(Header)
jwt의 헤더는 typ와 alg로 구성이 되어 있습니다.
typ : 토큰의 타입을 지정합니다. 당연히 JWT입니다.
alg : 해싱 알고리즘을 말합니다. 이 알고리즘은 토큰을 검증을 할때 사용되는 signature 부분에서 사용됩니다. 자주 사용하는 해싱 알고리즘은 HMAC와 SHA256입니다.
1-2.내용(Payload)
jwt의 페이로드는 jwt토큰에 담을 정보가 들어있습니다. 여기에 담는 정보의 한 ‘조각’ 을 클레임(claim) 이라고 부르고, 이는 name / value 의 한 쌍으로 이뤄져있습니다. 토큰에는 여러개의 클레임 들을 넣을 수 있습니다.
클레임의 종류에는 크게 3가지로 나뉠 수 있습니다.
- 등록된 클레임
- 비공개 클레임
- 공개 클레임
등록된 클래임
등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임들입니다. 등록된 클레임의 사용은 모두 선택적 (optional)이며, 이에 포함된 클레임 이름들은 다음과 같습니다:
- iss: 토큰 발급자 (issuer)
- sub: 토큰 제목 (subject)
- aud: 토큰 대상자 (audience)
- exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
- nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
- iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
- jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.
비공개 클레임
양 측간에 (보통 클라이언트 <->서버) 협의하에 사용되는 클레임 이름들입니다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야합니다.
공개 클레임
공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다.
1-3**.서명(signature)**
서명은 헤더의 인코딩값과, 정보의 인코딩값을 합친후 주어진 비밀키로 해쉬를 하여 생성합니다.
위의 3가지 부분에서 나온 값에 . 을 중간단자로 해서 연결을 하면 jwt의 토큰값이 완성이 됩니다.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MDAyNTQ4NTMsInN1YiI6ImFjY2Vzcy10b2tlbiIsImh0dHBzOi8vbG9jYWxob3N0OjgwODUiOnRydWUsInVzZXJJZCI6IndlbGw0MTQ5Iiwicm9sZSI6IlJPTEVfQURNSU4ifQ.Hry-gz_q4VlaoeK0KJmvDDLo8tdIP14us8I6h5ZS5F2gVviN2_hKYIEgUqmlEnjrchDFPRQm--yyIlq8EvGc9Q
그리고 위의 토큰값을 https://jwt.io/에 들어와서 토큰값을 입력을 하면 토큰에 대한 정보를 확인을 할 수 있습니다.
2.JWT와Session의 차이점
우선은 jwt 로그인 방식을 알기 전에 jwt가 나오기 이전의 인증방식인 session과cookie를 활용한 로그인 방식이 있다. 두 인증 방식을 보고 그에 따른 특징을 보도록 하자.
2-1. Session 기반의 인증
세션기반의 인가는 사용자의 인증 정보가 서버의 세션 저장소에 저장되는 방식이다. 사용자가 로그인을 하면, 해당 인증 정보를 서버의 세션 저장소에 저장하고, 사용자에게는 저장된 세션 정보의 식별자인 Session ID를 발급한다. 발급된 Session ID는 브라우저에 쿠키 형태로 저장되지만, 실제 인증 정보는 서버에 저장되어 있다.
브라우저는 인증 절차를 마친 이후의 요청마다 HTTP Cookie 헤더에 Session ID 를 함께 서버로 전송한다. 서버는 요청을 전달받고, Session ID에 해당하는 세션 정보가 세션 저장소에 존재한다면 해당 사용자를 인증된 사용자로 판단한다.
그럼 이 방식으로 하는 경우 어떠한 장,단점이 있을까?
장점
- 서버에서 사용자의 상태를 유지하고 있어, 사용자의 로그인 여부 확인이 용이하다. 경우에 따라 강제 로그아웃 등의 제재를 가할 수도 있다.
- 사용자가 임의로 정보를 변경하더라도 서버에서 사용자의 상태 정보를 가지고 있기 때문에 상대적으로 안전하다.
단점
- 서버에서 관리하기 때문에, 세션 저장소를 따로 이용하기에 요청이 많아지면 많아질수록 서버 부하가 심해진다.
- 세션방식은 Stateful상태이므로 서버 확장을 위해 scale-out을 하면 기존 서버에 있는 로그인 정보를 다른 서버에도 저장해야 하므로 중앙 세션 저장소를 필요로 합니다. 당연히 서버 비용 문제가 발생하게 됩니다.
2-3. Jwt 기반의 인증
토큰 기반 인증은 인증 정보를 클라이언트가 직접 들고 있는 방식이다. 이때 인증 정보가 토큰의 형태로 브라우저의 로컬 스토리지(혹은 쿠키)에 저장된다. 토큰의 종류에 따라 다르겠지만, 대표적인 토큰인 JWT의 경우 디지털 서명이 존재해 토큰의 내용이 위변조 되었는지 서버측에서 확인할 수 있습니다.
토큰 기반 인증에서는 사용자가 가지고 있는 토큰을 HTTP 의 Authorization 헤더에 실어 보낸다. 이 헤더를 수신한 서버는 토큰이 위변조 되었거나, 만료 시각이 지나지 않은지 확인한 이후 토큰에 담겨있는 사용자 인증 정보를 확인해 사용자를 인가합니다.
물론 이방식에도 장단점은 존재합니다.
장점
- 토큰이 클라이언트에 저장이 되므로 서버의 메모리에 저장 공간을 확보할 필요가 없다.
- 확장성이 뛰어납니다. 특히 모바일 환경에서는 이 방식을 사용해서 다양한 디바이스에서 사용할 수 있다.
단점
- HTTP를 통해서 전송하기 때문에 페이로드의 크기가 클수록 데이터 전송에 있어서 비용이 커진다.
- 유효기간을 따로 정하지 않는 이상 소멸되지 않기 때문에 장기간 방치시 해킹의 위험이 커진다.
- localstorage에 보관한다면 XSS공격에 취약해진다
※ XSS공격: 외부의 해커가 우리의 프로그램에 특정 javascript 코드를 심어서 localstorage에 접근하는 공격을 말합니다.
참고 사이트
https://hackernoon.com/using-session-cookies-vs-jwt-for-authentication-sd2v3vci
Using Session Cookies Vs. JWT for Authentication | HackerNoon
HTTP is a stateless protocol and is used to transmit data. It enables the communication between the client side and the server side. It was originally established to build a connection between web browsers and web servers.
hackernoon.com