쿠키(HTTP쿠키)
인터넷 사용자가 어떠한 웹사이트를 방문할 경우 그 사이트가 사용하고 있는 서버를 통해 인터넷 사용자의 컴퓨터에 설치되는 작은 기록 정보 파일
왜 쿠키(🍪)인가?
- 헨젤과 그레텔 동화에서 자신이 지나온 길을 표시하기 위해 쿠키조각을 바닥에 떨어뜨리는 것
= 서버에 요청한 사람이 누구인지 표시하기 위해 클라이언트에 쿠키를 남기는 것
- 유닉스 운영체제에서 두 프로그램 사이에 전송되는 작은 데이터 패킷을 매직 쿠키라 불렀는데, 이를 웹에서 차용해서 사용하기 시작한 것
특징
- 클라이언트에 저장된다
- 한 개에 4KB까지 저장 가능하다
- 이름, 값, 만료날짜, 경로 정보가 들어있다
- 기본적으로 웹브라우저가 종료되면 삭제되고(세션쿠키), 만료날짜를 지정해주면 만료일이 돼야 삭제된다(지속쿠키)
- 웹 브라우저에 해당 서버의 쿠키 정보가 있으면 HTTP 요청에 무조건 담아 보낸다
- 특정 도메인에서 생성된 쿠키는 해당 도메인에서만 사용가능하다.
세션(HTTP 세션)
서버에 클라이언트의 상태 정보를 저장해 놓고 이와 매칭되는 쿠키를 클라이언트에게 주어 서버가 클라이언트를 식별할 수 있도록하는 방식
왜 세션인가?
- session : 시간, 시즌
클라이언트와 서버간에 활성화된 접속 기간
이라는 의미이다.
- 통상적으로는
서버와 클라이언트간의 식별정보를 유효기간을 두고 저장하는 방식
을 통틀어서 세션방식이라고 부른다.
특징
- 따로 용량의 제한이 없다.
- 서버에 세션 객체를 생성하며 각 클라이언트마다 고유한 ID값을 부여한다.
- 쿠키를 사용하여 세션 ID값을 클라이언트에 보낸다.
- 웹 브라우저가 종료되면 세션쿠키는 삭제된다.
쿠키-세션 인증방식
장점
- 쿠키는 세션 저장소에 담긴 정보를 가져오기위한 열쇠역할일 뿐, 유의미한 값을 가지고 있지 않다. (중요 정보는 세션 저장소에 있다.)
- 사용자마다 고유 ID값을 발급받으므로 일일이 모든 회원정보를 확인하며 대조할 필요없이 회원정보에 접근 가능하다.
단점
- 특정 사용자의 HTTP요청을 해커가 가로채서 쿠키를 훔칠 수 있고, 훔친 쿠키를 이용해 요청을 보내면 세션저장소에서 정보를 잘못 뿌려주게된다.
해결책) https를 사용해 요청 자체를 탈취해도 안의 정보를 읽기 힘들게 한다.
- 서버에서 세션 저장소를 사용하므로 추가적인 저장공간이 필요함
해결책) 세션에 유효시간을 넣어준다.
세션이 만료되었습니다.
메이플 해본 사람은 다 아는 세션이 만료되었습니다.
대화창이다.
로그인 후 게임을 한참 하다가 다시 웹으로 돌아오면 위와 같은 대화창이 뜨면서 로그인이 풀린다. 로그인을 한 시점부터 세션만료 대화창이 뜨기까지의 과정을 추측해보자.
- 유저가 로그인을 시도한다.
- 서버에서는 유저 정보 테이블과 대조하여 일치하는 로그인 정보가 존재하는지 확인한다.
- 존재한다면 사용자의 정보를 세션 저장소에 저장하고 해당 데이터에 접근하기 위한 고유 세션ID를 발급한다.
- 세션 ID를 클라이언트에 보내고 이를 쿠키에 저장하도록 한다.
- 유저는 서버에서 받은 쿠키를 인증이 필요한 요청(ex. 게임 클라이언트 실행) 마다 헤더에 실어 보낸다.
- 유저로부터 받은 쿠키를 세션 저장소에서 대조한 후 대응되는 유효한 정보가 있는경우 인증이 완료되며 사용자에 맞는 데이터를 보내준다.
~ 재획 중 ...🍶 ~
- 1️⃣ 세션쿠키에 지정된 유효기간이 만료되거나
2️⃣ 쿠키가 삭제되거나
3️⃣ 서버에서 세션을 지워버리면(주로 서버에서 지정한 세션 유효기간이 만료되면)
로그인이 풀리면서 위와같은 대화창이 뜨게된다.
JWT
Json Web Token의 약자. 인증에 필요한 정보들을 암호화 시킨 토큰
JWT 형식
Encoded Header
+ .
+ Encoded Payload
+ .
+ Verify Signature
https://jwt.io/ 에 접속하면 실습해볼 수 있다 ^-^
꿀팁) jwt 토큰으로 팀즈에서 비밀얘기 할수있음 ㅋ
JWT 기반 인증 방식
장점
- 별도의 저장소 관리가 필요없다. (Stateless)
- 확장성이 뛰어나고 유지, 보수하는데 유리하다
- 토큰 기반으로 하는 다른 인증 시스템에 접근 가능 하다. (ex. 페이스북 로그인, 구글 로그인 등)
단점
- 이미 발급된 jwt에 대해서 돌이킬 수 없다. 세션/쿠키방식은 악의적인 접근이 예상되는 ID의 해당세션을 지워버리면 인증이 만료되지만 jwt방식은 불가능하다.
- payload에 넣을 수 있는 정보가 제한적이다. payload는 암호화 되지 않기 때문에 중요 정보는 넣을 수 없다.
- JWT의 길이는 세션/쿠키에 비해 길다. 요청이 많아질수록 서버의 자원낭비가 발생한다.
해결책) Access Token(유효기간 짧음)과 Refresh Token(유효기간 긺)을 함께 발급한다.
→ 저장소에 대한 고민이 필요하다... 주로 Access Token은 local storage에, Refresh Token은 서버사이드에 저장하며, Refresh token 의 index 값을 쿠키나 로컬스토리지에 저장하는 것 같다.
→ 프론트, 서버 모두 구현이 복잡해진다.
→ Access Token이 만료 될 때마다 새롭게 발급하는 과정에서 생기는 HTTP 요청 횟수가 많아 서버의 자원낭비가 발생한다 - 프론트단에서 Access Token payload를 통해 유효기간을 알아내 과정을 단축하자.
참고링크
https://tansfil.tistory.com/58
https://jwt.io/
이해가 잘되는 글이네요