http 무상태 프로토콜이다 --> 즉, 통신 이후에 어떠한 연결도 남지 않는다(stateless)
결과적으로, 사용자는 각각의 HTTP통신에 자신을 알릴 수 있는 정보를 주어야 한다
'자신을 알릴 수 있는 정보'의 역할을 하는 것이 바로 쿠키/세션/토큰 이다.
HTTP의 일종으로 사용자가 어떠한 웹 사이트를 방문할 경우, 서버에서 사용자의 브라우저에 저장하는 작은 기록 정보 파일이다.
서버가 쿠키를 만들어 브라우저에게 보내고,브라우저에서 저장했다가 요청을 했을떄 다시 서버에 보내주는 문자열이다.
클라이언트가 HTTP Request 를 서버에게 보냄
서버에서 유효성(회원인지)확인 후,쿠키를 생성한뒤, HTTP Response 헤더에 쿠키 넣어 응답
클라이언트는 HTTP Response의 header에서 쿠키를 추출하여 저장
클라이언트가 Request하고 싶을 때, HTTP가 해당 쿠키를 찾아 header에 자동으로 넣어서 전송
클라이이언트가 웹서버에 연결된 순간부터 웹 브라우저를 닫아 서버와의 통신을 끝낼 때 까지의 기간 이다. (서버가 클라이언트를 식별할 수 있도록 하는 방식자체를 의미)
서버에 세션에 대한 정보(세션 상태, 세션 데이터 등)를 저장해 놓고, 고유한 세션 ID를 쿠키에 저장해 클라이언트에 보내준다.
쿠키로만 인증수단을 가지면, 개발자도구열고 쿠키를 열어보면 누가 로그인했는지 알 수 있고, 데이터 조작도 가능하다.
따라서 직접적인 정보들을 암호화한 값이 세션이다.
중요한 정보는 서버에 저장하고,접근할 수 있는 세션키값만 브라우저에 저장한다.
클라이언트 HTTP Request를 서버에게 보냄
서버에서 유효성(회원인지)확인 후 고유한 Session-ID를 발급하여 쿠키에 넣고 HTTP Response header에 넣어 응답
클라이언트는 HTTP Response header에서 이 쿠키를 추출하여 저장
클라이언트가 HTTP Request를 보낼 때, HTTP가 해당 쿠키를 찾아 header에 자동으로 넣어서 전송
서버는 HTTP Request header에서 쿠키안에 Session-ID를 확인하고 통신
쿠키를 통해 클라이언트 로그인 상태를 유지시킬 수 있었지만, 가장 큰 단점은 쿠키가 유출 및 조작 당할 위험이 존재한다는 것이다. 개인정보를 HTTP로 주고 받는 것은 위험하다
따라서 서버에서 사용자에 맞는 세션id와 유저정보를 세션저장소라는 별도의 저장소로 저장하고
쿠키를통해 세션아이디를 쿠키에 담아 브라우저에 저장한뒤 http 요청이 있을때마다 쿠키가 자동으
로 담기는데, 이때마다 서버는 쿠키에 담긴 세션아이디와 세션저장소에 저장된 세션아이디를 비교해 인증을 한다.
stickey session(로드밸런서가 클라이언트 요청을 세션을 생성한 서버로만 전달),session clustering(모든 서버의 세션 동기화)등의 해결책이 있지만 확장성이 떨어진다는 문제는 여전하다.
1.토큰은 서버의 상태를 저장하지 않음 (Stateless) -> 토큰 자체로 정보를 가지고 있어 별도의 저장소필요(세션마냥) X
2.Access Token 을 HTTP 헤더에 실어 서버에 전송
3.토큰은 임의로 생성된 비밀번호 같이 동작한다. 제한된 수명을 가지고, 새로운 토큰은 한번 만료되면 새로 생성(Refresh Token).
4.가장 많이 사용되는 JWT는 JSON 포맷으로 저장하는 web token이다. (JWT(JSON Web Token)는 인증에 필요한 정보들을 암호화시킨 토큰을 의미합니다.)
header: 토큰의 타입,해싱알고리즘
payload: 사용자정보
signature: header,payload를 합친 문자열을 서버의 비밀키와 함께 암호화 한것
사용자가 로그인
서버에서는 계정 정보를 읽어 사용자를 확인 후, JWT 토큰의 유효기간을 설정
암호화할 Secret key 를 이용해 Access Token 을 발급
클라이언트는 Access Token 을 받아 저장 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냄
서버에서는 해당 토큰의 Verify Signature 를 Secret key 로 복호화한 후, 조작 여부, 유효기간을 확인
간편하다: 세션/쿠키 인증은 별도의 저장소 관리가 필요(서버쪽 저장소를 말하는것), 토큰은 발급한 후, 검증만 하기 때문에 추가 저장소가 필요하지 않는다.
1 .세션/쿠키 인증 방식은 쿠키가 악의적으로 이용될 경우 쿠키를 삭제하면 된다.
그러나 JWT 는 유효기간이 지나기 전까지 정보들을 이용할 수 있다.
이에 대한 해결책은, Access Token 유효기간을 짧게 하고 Refresh Token 이라는 새로운 토큰을 발급한다. 그렇게 되면 Access Token 을 탈취당해도 상대적으로 피해를 줄일 수 있다
3.payload는 암호화 되지 않기 때문에 유저의 중요한 정보를 담기 힘들다
1.사용자가 ID , PW를 통해 로그인
2.서버에서는 회원 DB에서 값을 비교(보통 PW는 일반적으로 암호화해서 들어감)
3~4.로그인이 완료되면 Access Token, Refresh Token을 발급한다. 이때 일반적으로 회원DB에 Refresh Token을 저장
5.사용자는 Refresh Token은 안전한 저장소에 저장 후, Access Token을 헤더에 실어 요청을 보냄
6~7.Access Token을 검증하여 이에 맞는 데이터를 보냄
8.시간이 지나 Access Token이 만료됐다고 보냄
9.사용자는 이전과 동일하게 Access Token을 헤더에 실어 요청을 보냄
10~11.서버는 Access Token이 만료됨을 확인하고 권한없음을 신호로 보냄
12.사용자는 Refresh Token과 Access Token을 함께 서버로 보냄
13.서버는 받은 Access Token이 조작되지 않았는지 확인한후, Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교한다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급
14.서버는 새로운 Access Token을 헤더에 실어 다시 API 요청을 진행
<Access Token 만료가 될 때마다 계속 과정 9~11을 거칠 필요는 없다. 사용자(프론트엔드)에서 Access Token의 Payload를 통해 유효기간을 알 수 있다. 따라서 프론트엔드 단에서 API 요청 전에 토큰이 만료됐다면 바로 재발급 요청을 할 수도 있다