[회고록] 프로젝트 기획: 기술 선택(2; 쿠키-세션-토큰)
HTTP(HyperText Transfer Protocol).
HTTP는 상태를 유지하지 않는 (stateless, 무상태) 프로토콜이다.
또한, 서버의 요청과 응답이 모두 끝난 후에는 연결을 끊어버린다. 즉, 비연결성(Connectionless)을 가진 프로토콜이다.
이러한 HTTP 특성을 생각해보면,
'어, 그럼 지금 내가 티스토리에 어떻게 로그인해있지?' 라는 의문이 들 것이다.
HTTP 특성 그대로 생각하면,
서버에 로그인 정보와 함께 요청한다 -> 서버는 정보를 통해 인증 후 응답한다. -> 연결 종료
로그인을 유지할 수 없다.
그냥 서버는 '어 그래 너야? 너 맞아~' 이러고 응답만 해주고 연결이 끊기는 거다.
이런 상태를 기억하지 못한다는 특성 때문에,
쿠키, 세션, 토큰이 사용된다.
쿠키(Cookie)
쿠키는.. 다 알 거라고 생각한다.
사용자의 브라우저에 저장하는 방식이다.
서버가 클라이언트 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 저장한다.
이렇게 저장된 정보는 클라이언트가 요청할 때마다 (헤더의 쿠키에) 담아져 보내진다.
서버는 이 정보로 '아 얘가 걔?' 가 가능해지는 거다. (어떤 클라이언트가 요청 했는지 알 수 있다는 말 ㅎㅎ)
근데 누가봐도, 보안적으로 되~게 안 좋아보인다.
우리집 컴퓨터 아니고, PC방 가서 로그인하는데. 그 브라우저에 내 개인정보를 저장한다고? (싫어영~)
세션(Session)
쿠키가 사용자의 브라우저에 정보를 저장하는 방식이면,
세션은 서버에 따로 세션 저장소를 둬서 그곳에 사용자 정보를 저장하는 방식이다.
이 저장소에는 세션ID, 사용자 정보(id, ..), 세션 유효기간 등의 정보가 저장된다. (사용자 정보에 비밀번호와 같은 민감한 정보는 들어가지 않는다. (보안 상의 이유로 세션에는 최소한의 인증 정보만 저장하는 것이 원칙이라 한다.))
이 세션 방식은 거의 쿠키와 같이 이용되는데, 쿠키에 세션 id만 저장하는 것이다. 이 쿠키는(a.k.a 세션쿠키) 브라우저가 닫히면 자동으로 삭제된다고 한다.
이 쿠키에 있는 정보로 세션에 있는 클라이언트의 정보를 사용하는 것이다.
작동 방식을 써보자면 이렇다.
클라이언트의 요청 -> (인증 됐다는 가정 하) 서버에서 세션id 발급 -> 클라이언트 응답할 때 세션id를 쿠키에 저장하여 같이 보냄
-> 클라이언트 요청(+ 세션 id) -> 서버는 해당 세션 id로 클라이언트 정보를 갖고 요청 처리 후 응답
세션 저장소를 위한 새로운 인프라가 필요하다는 점이 단점이다. (따로 두지 않아도 가능은 하나, 사용자 수가 늘어나면 서버의 부하가 생겨 서비스가 제대로 작동하지 않을 수 있다.)
토큰(Token)
토큰 방식은 세션+쿠키 방식이 메모리를 많이 사용한다는 단점에 의해 등장했다.
토큰은 사용자 정보를 암호화시킨 것이다.
그 중 JWT 토큰 방식을 대부분 사용하는 것으로 알고 있다.
JWT 토큰의 특징으론 크게 두 가지가 있다.
1. signature(서명)를 통해 변조를 방지한다.
2. 토큰은 클라이언트에 저장되어, 서버에서 직접 관리하지 않고 일관된 상태를 유지하는 데 노력하지 않아도 된다. (stateless)
JWT 토큰을 통한 인증 방식은 이렇다.
1. 클라이언트가 요청한다
2. (인증 됐다는 가정 하) 서버에서 Access Token 과 Refresh Token을 생성하여 클라이언트에 응답한다. Refresh Token만 HttpOnly 속성을 가진 쿠키에 저장한다.
3. 클라이언트는 응답받은 Access Token을 로컬 스토리지(Local Storage)에 저장한다.
4. 클라이언트는 요청할 때마다 Authorization 헤더에 Access Token을 포함하여 서버에 요청한다.
5. 서버는 해당 Access Token을 검증하여 사용자의 인증 상태와 권한을 확인하여 응답한다.
5-1. Access Token이 만료되었거나 유효하지 않은 경우, 쿠키에 있는 Refresh Token의 유효성을 검증하여 Access Token을 재발급한다. 만약, Refresh Token도 만료되었거나 유효하지 않은 경우, 사용자는 재 로그인을 해야한다.
※ HttpOnly 속성을 가진 쿠키는 JavaScript로 접근할 수 없는 보안 기능을 제공한다.
우리는 토큰 방식으로 로그인 기능을 구현하기로 했다.
여기서 우리는 Refresh Token을 어떻게 저장할지 고민했다.
그 고민 과정은 다음 글에 쓰도록 하겠당