최근에는 OAuth나 자체적으로 Token을 발행하는 인증 방식을 많이 취한다.
하지만 여전히 레거시한 서비스에서는 Session을 사용하는 경우도 있다.
그간 로그인, 회원가입처럼 인증/인가를 구현할 때 세션과 토큰에 대해서 얼핏 알고는 있었지만 깊게 이해하지는 못한 상태였기에 한번 공부 해보려 한다.
HTTP 통신은 Stateless한 특징을 갖고 있다.
즉, 상태가 없어서 요청과 응답의 과정만 존재한다. 하지만 지금의 웹서비스는 ID와 비밀번호로 본인 확인을 요청하고 난 이후, 로그인이 되어있는 '상태'로 해당 웹서비스가 제공하는 다른 페이지를 이용할 수 있다.
이것을 가능하게 하는 방법 중 하나인 세션에 대해 알아 보고자 한다.
세션의 등장에는 쿠키(Cookie)를 빼놓고 얘기할 수 없다.
쿠키는 상태 정보를 클라이언트에서 보관하고 있는 것이다.
문제는 비밀번호와 같이 사용자 본인의 프라이버시 노출에 취약한 정보가 쿠키에 저장되어있다면 다른 사람들도 볼 수 있는 소지가 생긴다는 것이다.

물론 지금은 옵션을 설정하여 Js에서 접근하지 못하도록 할 수도 있겠지만 본래 쿠키는 위처럼 접근할 수 있다는 것을 볼 수 있다.
세션은 민감한 정보를 클라이언트가 보관하지 않고, 서버에서 보관한다.
그리고 그를 Hashing(해싱)?하여 난해한 문자열로 id를 발급해 클라이언트용으로 세션-쿠키를 발급한다.
그래서 쿠키에 비해 비교적 안전한 인증 확인을 할 수 있다..
결국 세션도 쿠키와 같이 클라이언트의 상태를 다른 페이지에 걸쳐서 유지시키는 기능을 한다고 할 수 있다. 하지만 여전히 문제점은 남아있다.
결국 다른 이용자가 세션을 탈취하여 서버에 신원확인을 요청하면 유효하기에 악용할 여지가 있다.
결국 세션의 ID가 담기는 쿠키에 대한 제한이 이루어졌다.
쿠키에 담길 수 있는 정보들을 알아보자.
- Secure :
Secure가 지정되어있는 Cookie는 https 프로토콜을 사용하는 암호화 전송에서만 이용이 가능한 쿠키다.- HttpOnly :
Cross-Site Script(CSX) 공격에 대응하기 위하여 Http 통신에서만 사용 가능한 쿠키로 지정하는 옵션이다. 위에서처럼 Js로 쿠키에 접근이 불가능하다.
특히 세션에 대한 정보는 서버에서 관리를 하기 때문에 HttpOnly를 꼭 사용하는 편이다.- SameSite:
Cross-Origin을 허용하지 않고 같은 도메인을 사용하는 서버에만 전달되어진다.
모든 브라우저에서 제공되는 기능은 아니라고 한다.- Domain :
SameSite와 비슷한데, 쿠키를 주고 받을 수 있는 Domain 주소를 지정하는 것이다.
예를 들어 "velog.io"를 지정했다면, 해당 주소를 사용하는 서버하고만 쿠키를 주고 받을 수 있다.- Path :
쿠키가 전송되어 최종적으로 사용되는 경로를 지정할 수 있다.
"user/login" 같은 형식으로 지정하면 된다.
서버 측에서 응답으로 보내는 헤더의 Set-Cookie 예시는 다음과 같을 것이다.
Set-Cookie : id=3asdw; Secure; HttpOnly; SameSite;
쿠키를 이와 같이 명시하여 발급해주면 쿠키가 악의적으로 탈취되는 것을 조금 예방할 수 있다.
하지만 완전한 해결책은 아니다.

요청 측 헤더의 옵션 중 하나인 WithCredentials에 관한 것이다.
클라이언트 측에서 서버에 인증 요청을 할 때 헤더로 Credential 체크 여부를 먼저 확인한다.
서버 측에서는 해당 여부에 대해 Access-Control-Allow-Credentials를 응답 헤더에 true 값으로 반환을 해줘야 비로소 자격증명에 관련한 작업들을 클라이언트에게 전해줄 수 있다.
Credentials란 쿠키, Authorization(인증헤더), TLS client certificates(증명서)를 말한다.
const corsOption = {
credentials : true,
origin : ["https://localhost:XXXX"],
method : ["GET", "POST", "OPTIONS"],
}
위처럼 cors 미들웨어를 써서 옵션을 해준다던지 했을 때 credentials 정책 여부를 확인하고 진행이 된다.
세션의 정보가 서버에 저장된다는 것이다.
수십 명의 정보가 저장이 된다면 부하는 크지 않음 그러나 접속하는 인원이 예상을 웃도는 다수라면, 이들에 대한 정보를 서버에서 유지한다 했을 때 자원이 많이 쓰인다.
보통 지정을 안해주면 세션은 서버의 메모리에서 관리하게 된다.
온메모리 데이터를 따로 데이터베이스에 저장하여 관리한다고 해도, 어쨋든 서버의 관리를 요한다.
결국 이 때문에 비교적 덜 민감한 정보들과 함께 인증 요청에 대해서는 Token을 이용하여 클라이언트가 들고 있게 한다.