[Authentication] Cookie & Session

Jiyoung·2021년 3월 12일
0

쿠키(Cookie)란?

쿠키(Cookie)는 어떤 웹사이트에 들어갔을 때 서버가 일방적으로 클라이언트에 전달하는 작은 데이터를 의미한다. 즉 쿠키는 클라이언트에 정보를 저장하는 방식으로, stateless(무상태성)라는 속성을 갖는 HTTP에 정보가 유지될 수 있는 것이 바로 쿠키 덕분이다. 서버는 웹 브라우저에 쿠키를 저장하고, 해당 도메인에 대해 쿠키가 존재하면 웹 브라우저는 도메인에게 http 요청 시 쿠키를 함께 전달한다.
이미지 출처: codestates urclass

쿠키는 삭제하지 않으면 사라지지 않기 때문에 장기간 보존해야하는 정보(ex. 장바구니 저장, 로그인 상태 유지, 테마 등)를 저장하는 데 적합하다.

쿠키 옵션(Cookie Options)

서버는 쿠키를 이용하여 데이터를 저장하고 원할 때 이 데이터를 다시 불러와 사용할 수 있다. 그러나
데이터를 저장한 이후 아무 때나 데이터를 가져올 수 있는 것이 아니라, 특정 조건들을 만족하는 경우에만 다시 가져올 수 있다. 이런 조건들은 쿠키 옵션으로 표현할 수 있다.

  1. Domain: 서버와 요청의 도메인이 일치하는 경우 쿠키 전송
  2. Path: 서버가 라우팅할 때 사용하는 경로, 서버와 요청의 세부경로가 일치하는 경우 쿠키 전송
  3. MaxAge or Expires: 쿠키의 유효기간 설정(일정 시간 후 자동 소멸)
  4. HttpOnly: 자바스크립트에서 브라우저의 쿠키 접근 여부를 결정. 쿠키는 script태그로 접근할 수 있기 때문에 XSS 공격에 취약함, 따라서 쿠키에는 민감한 정보나 개인정보는 담지 않는 것이 좋음.
  5. Secure: HTTPS 프로토콜에서만 쿠키 전송 여부 결정
  6. SameSite: CORS 요청의 경우 옵션 및 메소드에 따라 쿠키 전송 여부 결정. CSRF공격을 막을 수 있는 매우 효과적인 옵션.
    -Lax: Cross-Origin 요청이면 'GET' 메소드에 대해서만 쿠키 전송 가능
    -Strict: 쿠키 전송 불가
    -None: 모든 메소드 요청에 대해 쿠키 전송 가능, HTTPS프로토콜과 Secure쿠키 옵션이 필요함

이러한 옵션들을 지정한 후 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면 헤더에 Set-Cookie라는 프로퍼티에 쿠키를 담아 쿠키를 전송하게 된다. 이후 클라이언트 혹은 서버에서 쿠키를 전송해야 한다면 클라이언트는 헤더에 Cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.

이러한 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless 한 인터넷 연결을 Stateful 하게 유지할 수 있다.

그러나 쿠키는 오랜 시간 동안 유지될 수 있고, 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 인증정보가 유출될 수 있는 위험이 있다. 따라서 클라이언트에 오랜 시간 저장이 가능하다는 특징은 장점이자 단점이 되어서 쿠키에 인증 정보를 담아 보관하는 쿠키 기반 인증 방식은 많이 사용되지 않는 방법이 되었다.

다만 인증정보 대신에 쇼핑몰 장바구니 저장, 테마 설정 유지 등 민감하지 않은 정보나 여러 옵션을 장기 보관하는 용도로 유용하게 사용되고 있다.

웹 브라우저 접속 => 서버가 쿠키를 클라이언트에 저장 => 해당 도메인에 대해 쿠키가 존재하면 웹 브라우저는 도메인에게 http 요청 시 쿠키를 함께 전달 => 지속적으로 로그인 정보를 가지고 있는것처럼 사용


세션(Session)이란?

세션(Session)데이터를 서버에 저장하는 방식으로, 쿠키에는 그 데이터에 대한 id만 암호화된 상태로 부여한다. 중요한 데이터는 서버에서 관리한다.
이미지 출처: codestates urclass

세션은 서버의 메모리에 세션 정보를 저장하고 있는데, 서버의 이용자가 매우 많다면 메모리의 일정 공간을 항상 차지하고 있게 되므로 가용 메모리의 양이 줄어들어 서버의 성능이 떨어질 수 있다는 단점이 있다. 또한 세션은 기존 쿠키를 이용하기 때문에 XSS공격으로 인해 세션 아이디가 담긴 쿠키가 탈취될 경우 개인정보가 유출될 수 있다는 위험이 여전히 존재한다.

세션 기반 인증(Session-based Authentication)

유저 인증정보는 더이상 쿠키에 담기지 않고 각각의 세션 객체에 저장된다. 따라서 로그인 이후 각각의 세션 객체에 해당 유저의 인증정보를 저장하는 로직이 필요하다.

유저 인증정보를 저장하고 나면, 서버는 매 요청마다 해당되는 세션 객체에 저장된 유저 인증정보를 바탕으로 유저정보 요청과 같은 인증이 필요한 요청이 이전에 인증된 유저의 요청인지 검증 할 수 있다.
쿠키에는 인증정보 대신 세션 아이디를 저장한다.

쿠키를 통해서 유효한 세션 아이디가 서버에 전달되고, 세션 객체에 해당 세션 아이디에 유저의 인증정보가 존재한다면 서버는 해당 요청이 유저정보에 접근 가능하다고 판단한다. 하지만 쿠키에 세션 아이디 정보가 없거나 해당 세션 객체에 유저 인증정보가 존재하지 않는경우, 서버는 해당 요청이 유저정보에 접근하게 두어서는 안된다.

또한 서버는 로그아웃 요청을 반드시 필요로 한다. 세션 아이디가 담긴 쿠키는 인터넷 탭을 닫으면 삭제되지만, 유효기간이 따로 정해져 있지 않기 때문에, 세션 아이디 쿠키가 유출된 상태에서는 해당 쿠키를 이용한 요청이 유출된 쿠키를 이용한 공격인지, 정말로 사용자가 요청을 보낸건지 서버는 확인할 방법이 없으며, 서버는 쿠키의 유출 여부조차 알수 없다. 따라서 서버에서 세션을 파괴하는 과정이 반드시 필요하다.

클라이언트는 서버접속시 세션 ID를 발급받음 => 클라이언트는 세션ID에 대해 쿠키를 사용해서 저장 => 서버요청시에 이 쿠키의 세션ID를 서버에 전달하여 사용 => 서버는 받은 세션ID로 세션의 클라이언트정보를 가져오고 서버요청을 처리하여 클라이언트에게 응답


express-session

express-session은 세션을 위한 미들웨어로, express에서 세션을 다룰 수 있는 공간을 보다 쉽게 만들어준다.

또한 필요한 경우 세션 아이디를 쿠키에 저장하고, 해당 세션 아이디에 종속되는 고유한 세션 객체를 서버 메모리에 저장한다. 이때 세션 객체는 서로 독립적인 객체이므로 각각 다른 데이터를 저장할 수 있다.

req.session이 바로 세션 객체이며, req.session은 세션 객체에 세션 데이터를 저장하거나 불러오기 위해 사용한다.

세션 객체 생성

req.session.regenerate(function(err) {
  // will have a new session here
})

세션 객체에 변경된 값 저장

req.session.save(function(err) {
  // session saved
})

세션 객체의 데이터 삭제

req.session.destroy(function(err) {
  // cannot access session here
})

브라우저에서 서버로 요청을 했을 때 express-session에서는 해당 브라우저의 고유아이디를 참고하여 그에 해당하는 세션 하나가 반환되어 req.session 객체에 담겨진다. 따라서 req.session.distory()를 한다해서 해당서버의 모든 세션이 사라지는 것이 아닌, 활성화되어 처리를 하고 있는 해당 브라우저의 정보만 사라지게 된다.
참고링크

설명접속상태 저장경로장점단점
Cookie-(쿠키)HTTP의 Stateless한 속성을 보완클라이언트서버의 부담을 덜어줌쿠키 그 자체는 인증이 아님
Session--(세션)접속 상태를 서버가 갖고, 접속 상태와 권한부여를 위해 세션아이디를 쿠키로 전송서버신뢰할 수 있는 유저인지 서버에서 추가로 확인 가능하나의 서버에서만 접속상태를 가지므로 분산에 불리함

참고 자료

CodeStates Urclass 내 강의 자료

profile
경계를 넘는 삶

0개의 댓글