Session(쿠키)과 Token 필요 이유 HTTP의 특징 때문
HTTP(Stateless)
- 웹 환경에서 사용자와 서버 간에 데이터를 교환하기 위해서 HTTP 방식을 사용 함.
- HTTP의 가장 큰 특징은 Stateless
- 각각의 HTTP 요청은 독립적이라 과거의 요청을 기억하지 않음.
- 매 통신마다 필요한 모든 정보를 담아 요청해야 한다는 것.
- 예) 로그인 후 상품구매 - 매 요청마다 로그인을 위한 인증정보를 보내야 함.
😽 이 불편함을 해결하고자 Session과 Token 기술을 사용
Session & Cookie
Cookie(전달 매개체)
- 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일.
- 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있음.
- 쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조함.
- 클라이언트에 300개까지 쿠키저장 가능, 하나의 도메인당 20개의 값만 가질 수 있음, 하나의 쿠키값은 4KB까지 저장함.
- Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있음.
- 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송함.
cookie의 구성
- 이름
- 값
- 유효시간
- 도메인 : 쿠키를 전송할 도메인
- 경로 : 쿠키를 전송할 요청 경로
쿠키의 동작 방식
- 클라이언트의 페이지 요청
- 서버에서 쿠키 생성
- HTTP 헤더에 쿠키를 담아 응답
- 브라우저가 종료되어도 쿠키 만료기간이 설정되어 있으면 브라우저에서 보관
- 같은 요청일 경우 HTTP 헤더에 쿠키를 담아 요청
- 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 대 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함하여 응답.
쿠키 사용 예
- 로그인 시 ID PW 저장 여부
- 장바구니
- 자동로그인, 팝업에서 더 이상 보지 않음 체크
Session
세션이란?
-
동일한 클라이언트가 브라우저를 통해 서버에 접속한 시점부터 브라우저를 종료하여 연결을 끝낼 때 까지를 하나의 Request로 보고 그 상태를 유지하여 클라이언트와 서버가 논리적으로 연결된 상태.(stateful)
-
세션은 쿠키에 기반하지만 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리
-
서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여, 웹 브라우저가 서버에 접속하여 브라우저 종료 시까지 인증상태 유지
-
접속 시간에 제한을 두어 일정 시간 응답 없으면 정보가 유지되지 않는 설정 가능
-
사용자에 대한 정보를 서버에 둬서 보안성이 좋다, 하지만 사용자가 많아지면 서버 과부하
-
클라이언트의 리퀘스트에 서버의 엔진이 클라이언트에게 고유 ID를 부여한다. 이것이 세션 ID
세션 동작 방식
사용자 로그인 요청 -> 로그인 통과 -> 쿠키에 세션ID 유무 파악..
-> 있으면 DB에 일치하는 세션 뒤져서 응답
-> 없으면 세션 ID를 생성해서 DB에 저장하고 응답 헤더에 세션 ID를 포함시켜 보냄.
-> 해당 세션 ID가 포함된 쿠키가 브라우저로 돌아와서 저장됨.
-> 이제 요청에 세션ID가 세션쿠키에 저장되어 전달됨-> 서버는 세션ID를가지고 세션 DB에 확인
-> 이 프로세스 반복.(중요 유저정보 모두 서버에서 유지됨)- 유저는 세션 ID만 가지고 있음
-> 브라우저를 종료하거나 응답 시간 경과 시 쿠키는 삭제 됨.
또한 모바일 IOS나 안드로이드에 세션은 있지만 쿠키는 브라우저만 있는거라 사용 불가.
이 경우 토큰을 사용함.
세션의 또 하나의 문제점은 서버는 매 요청마다 세션아이디 쿠키를 받고
해당하는 아이디와 일치하는 세션을 찾아야하고 그 후에야 작업을 수행할 수 있음.(유저 증가 디비 리소스 증가)
session 기반 인증 특징
장점
- 클라이언트 측의 세션ID에는 유의미한 정보가 없고 서버에서 사용자 정보와 데이터를 유지하여 보안과 안정성이 좋다.
- stateful 상태로 사용자의 로그인 여부, 관리를 하기 쉽다.
- 세션 ID로 클라이언트를 구분하여 요구에 맞는 서비스를 제공.
단점
- 서버에서 모든 사용자의 상태를 관리하여 부하가 증가
- 사용자가 증가하여 서버 확장시 세션관리가 어렵다.(확장성 안좋음)
- CORS : 웹어플리케이션에서 세션을 관리할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있기 때문에 쿠키를 여러 도메인에서 관리하기는 비효율적이다.
쿠키와 세션의 차이
- 쿠키와 세션은 역할도 비슷하고 동작원리도 비슷함. (쿠키 기반이기 때문에)
- 가장 큰 차이점은 사용자의 정보가 저장되는 위치.(세션 서버 자원 사용/ 쿠키는 안함)
- 세션이 보안성 우수 but 쿠키는 빠름.
- 쿠키는 클라이언트 로컬에 저장되어 변질, 스니핑 당할 우려
- 쿠키는 만료 기한을 정하여 기한 도달 시 삭제 가능 but 세션은 기한 정해도 브라우저 종료되면 삭제
- 쿠키는 정보를 담고 있어 속도가 빠르지만 세션은 서버에 정보가 있어 처리 시간이 소요되어 상대적을 느림.
캐시와 쿠키/세션의 차이
캐시?
Cache
- 캐시는 서버 부하를 방지하기 위해 웹 문서, 이미지 등의 자원을 임시 사용자 웹 브라우저에 저장하는 기술. HTTP 통신시 임시 저장된 캐시가 있으면 불필요한 전송을 줄이고 서버에 불필요한 요청을 줄여주어 빠른 통신으로 페이지 로딩 속도를 개선한다.
차이
- 캐시는 이미지나 파일 등을 브라우저나 서버 앞 단에 저장해놓고 사용
- 한번 캐시에 저장되면 브라우저를 참고하기 때문에 서버에서 업데이트가 있어도 사용자 측에서는 업데이트 전을 보게 됨.( 캐시를 지우거나 서버에서 캐시 만료 기간을 설정해두는 것으로 해결)
웹 스토리지
- 클라이언트에 데이터를 저장할 수 있도록 HTML5부터 나온 새로운 방식의 데이터 저장소
- 로컬 스토리지와 세션 스토리지
- Key-value 쌍 형태
- window 객체의 프로퍼티로 존재
웹 스토리지의 특징
장점
- 서버에 불필요한 데이터 저장x
- 넉넉한 데이터 저장 용량
- 문자열 외에도 JS의 모든 데이터타입 저장 가능
- 도메인 단위로 접근이 제한되는 CORS 특성으로 CSRF에서 안전
단점
- HTML5 지원 브라우저만 사용 가능
- XSS로부터 위험 - local storage에 접근하는 JS 코드로 쉬운 접근
로컬, 세션 스토리지 차이
- 로컬 스토리지는 데이터 영구 저장이 가능, 세션 스토리지는 브라우저의 탭이나 윈도우가 닫히면 초기화
- 로컬은 window.localStorage / 세션은 window.sessionStorage 객체 사용
- 로컬은 오리진만 같으면 탭 달라도 유지
- 세션은 탭별로 관리
쿠키, 로컬 스토리지, 세션 스토리지 사용처
- 쿠키: 일시적 필요한 가벼운 데이터 (팝업, 로그인 자동완성)
- 로컬 : 지속적 필요 데이터 저장 (자동 로그인)
- 세션 : 일시적 필요 데이터 저장(일회성 로그인, 입력 폼 저장, 비로그인 장바구니)
JWT(정보를 담고 있는 토큰)
JWT란
-
클라이언트- 서버 간 정보를 JSON 객체로 안전하게 전송하기 위한 개방형 표준
-
JWT는 JSON개체에 기본정보, 전달 정보, 검증 정보를 모두 담고 있음.
-
전자서명이 되어 있어 검증 과정을 거쳐 확인하고 신뢰 가능
-
Token은 제한된 리소스에 대해 일정 기간 동안 접근 할 수 있는 권한을 가지며 일종의 정보를 담고 있는 토큰.
-
JWT 인증은 사용자 측에서 사용자의 정보를 관리하는 토큰 기반 인증 메커니즘.
-
서버에서 세션 정보를 저장하기 위해 세션 스토리지 또는 데이터베이스에 완전히 의존할 필요가 없음
-
서버의 확장성과 멀티기기 및 도메인에서 활용에도 이점을 가지고 있음.
JWT flow
- 토큰기반은 stateless로 세션을 두지 않아 유저의 로그인 여부와 상관없이 확장이 용이해짐.
(1) 클라이언트가 유저 ID, Password 데이터를 담아 로그인을 서버에 요청
(2) 서버에서 유저 인증을 위해 전달받은 클라이언트 데이터를 Database에서 조회
(3) Database에서 인증 완료시, 서버는 JWT Token을 생성 및 클라이언트에게 전달
(4) Database에서 인증 실패시, 회원가입을 요청하며 회원가입 후 Database에 유저 정보를 추가하고 JWT Token 생성 및 클라이언트에게 전달
(5) 클라이언트는 전달받은 JWT Token을 쿠키 또는 로컬스토리지 또는 세션 스토리지에 저장
(6) 클라이언트가 인가가 필요한 페이지에 접속할 때마다 HTTP Header에 JWT Token이 담긴채로 서버로 전송
(7) 서버는 이 토큰을 디코딩해서 클라이언트 인가를 처리하고 요청한 데이터를 전송
TOKEN?(신분증)
- 토큰은 임의로 생성된 string이며 제한된 수명을 가지고 한 번 만료되면 새롭게 생성되어야 함.
- 신분증이라고 보면 됨
JWT 구조
aaaaaa.bbbbbb.cccccc
헤더(header) / 내용(payload) / 서명(signature)
{
"typ": "JWT", // 토큰의 타입 지정
"alg":"HS256",
//해싱 알고리즘, 이 알고리즘은 토큰을 검증할 때 사용되는
// 시그니쳐 부분에서 사용됨.
}
보통 토큰화는 라이브러리가 알아서 해주지만
어떤 과정인지 알고 싶다면 LINK
정보(payload)
- payload에는 토큰을 담을 정보가 들어있음.
- 정보의 한 조각을 클레임(claim)이라고 함.
- 클레임은 name/value 한 쌍으로 이루어짐
- 토큰에는 여러개의 클레임을 넣을 수 있음.
클레임의 종류
- 등록된 (registered) 클레임,
- 공개 (public) 클레임,
- 비공개 (private) 클레임
등록된 클레임.
- 서비스에 필요한 정보가 아닌 토큰에 대한 정보를 담기 위하여 이미 이름이 정해진 클레임.
- 사용은 optional.
공개 클레임
- 공개 클레임들은 충돌이 방지된 이름을 가져야 함
- 이를 위해서 이름을 URI형식으로 짓는다.
{
"https://velopert.com/jwt_claims/is_admin": true
}
비공개 클레임
- 등록도 공개도 아닌 클레임
- 서버와 클라이언트 협의간에 사용되는 클레임 이름.
- 중복 주의
예제 payload
{
"iss": "velopert.com",
"exp": "1485270000000",
"https://velopert.com/jwt_claims/is_admin": true,
"userId": "11028373727102",
"username": "velopert"
}
서명(signature)
- JWT의 마지막 부분
- 헤더의 인코딩값과 정보의 인코딩 값을 합치고 주어진 비밀키로 해쉬를 하여 생성
생성 과정 보기 LINK
JWT의 장점
1. Stateless
- 서버는 상태 유지할 필요 없이 클라이언트에서 들어오는 서명된 토큰을 검사하기만 하면 됨.
2. scalability(확장성)
- 클라이언트-서버 간 연결 고리가 없기 때문에 확장성이 증가
3. 보안성이 개선
- 쿠키를 사용하지 않기 때문에 쿠키의 취약점 없어짐
- 토큰의 만료 시간을 짧게 하여 안정성을 높임
4. Extensibility(확장성)
- 로그인 정보가 사용되는 분야의 확장성이 좋아짐
- 토큰을 사용하면 다른 서비스에도 권한 공유가 가능해진다.
- 대표적으로 OAuth는 페이스북/ 구글 같은 소셜 계정들을 통해 다른 웹 서비스에서 로그인 할 수 있게 함.
5. 여러 디바이스 및 도메인
- 토큰만 유효하다면 어떤 도메인에서도 정상적인 요청이 가능(CORS 해결 용이)
- 토큰을 이용하면 웹이든 모바일이든 토큰의 유효성 검사만 하면 돼서 Request 처리 가능
- 단 서버에서 Access-Control-Allow-Origin: *(or 해당 도메인) 설정 해줘야 함.
6. 웹 표준 기반
- 토큰 기반 인증 시스템인 JWT는 웹표준에 등록되어 많은 회사가 이용중
7. 자가수용적(self-contained)?
- JWT는 필요한 모든 정보를 자체적으로 지니고 있다.
- 기본정보, 전달 할 정보(예; 로그인 시 유저 정보), 시그니쳐(토큰 검증 증명)
JWT의 단점
- 서버에서 사용자의 상태를 유지하지 않아 로그인 여부나 강제 로그아웃 등이 어렵다
( 만료기간이 끝나기 전까지 토큰을 임의로 만료시킬 수 없기 때문)
- JWT가 브라우저에 그대로 노출되어 있어 위변조, 손상의 위험이 커서(XSS공격에 취약)
- 세션 아이디보다 길기 때문에 HTTP Request 전송 데이터 크기 증가
참고
https://interconnection.tistory.com/74 - 세션과 쿠키의 차이
https://velopert.com/2389 - JWT
https://velog.io/@hs0217/JWT - JWT 플로우
https://study.wecode.co.kr/session/content/320 나만 접속 가능.