세션 인증 방식과 쿠키

눈사람·2024년 8월 12일
0

인증을 할 수 있는 방식은 다양하다. OAuth를 사용해서 카카오톡이나 구글 등 다른 플랫폼에서 인증을 받아 권한을 부여할 수도 있고, JWT(JSON Web Token)로 로그인을 구현할 수도 있다. 또한 쿠키 인증 방식을 사용할 수도, 세션 인증 방식을 사용할 수도 있다.
지금 하고 있는 프로젝트에서 세션 인증 방식을 사용하기 때문에 이에 대해 더 자세히 알아보기로 했다.

세션(Session) 인증 방식

세션이란?

세션은 데이터를 서버에 저장하는 방식이다. 세션은 브라우저로 웹서버에 접속한 시점부터 브라우저를 종료하여 연결을 끝내는 시점까지의 일련의 요청을 하나의 상태로 간주하고, 그 상태를 일정하게 유지하는 기술이다.

세션 인증 방식

세션 인증 방식은 세션으로 사용자의 인증 정보를 관리하는 방식이다.

1. 클라이언트가 서버에 로그인 요청을 보내면, 서버에서 인증 정보를 저장하고 SessionID를 클라이언트에게 제공한다.
2. 서버에서 받은 SessionID로 서버에게 인증/인가 요청을 하여 서버에서 SessionID에 해당하는 인증 정보로 인증/인가를 처리한다.

여기서 클라이언트는 SessionID를 서버에게 전송하기 위해 쿠키를 사용할 수 있다.

쿠키(Cookie)🍪

쿠키는 서버가 사용자의 웹 브라우저에 전송하는 데이터 조각이다.

브라우저는 쿠키를 저장할 수도, 새로운 쿠키를 만들수도, 존재하는 쿠키를 수정할 수도 있으며, 이후 해당 서버로 응답할 때 쿠키를 다시 전송할 수 있다.

쿠키를 사용하는 이유

쿠키는 웹 애플리케이션이 제한된 양의 데이터를 저장하거나 HTTP 프로토콜이 무상태(stateless)임에 따라 상태 정보를 기억하기 위해 사용한다.

HTTP 프로토콜이 무상태이기 때문에 클라이언트가 따로 사용자 정보를 포함해서 요청을 보내지 않는 이상 서버는 클라이언트를 구분할 수 없다. 클라이언트로부터 요청이 들어와도 이것이 이전에 요청을 보낸 사용자인지 새로운 사용자인지 구분할 수 없다는 뜻이다.
보통 서버는 HTTP 쿠키의 정보를 이용하여 해당 요청이 같은 브라우저(사용자)에게서 온 것인지를 확인하고 개인화된 응답을 또는 일반적인 응답 중 적절한 것을 보낸다.

쿠키는 주로 아래의 세가지 목적으로 사용된다.

  1. 세션 관리(Session management): 로그인 상태, 장바구니, 게임 점수 등 서버가 기억해야하는 사용자 세션과 관련된 정보들을 관리하기 위해
  2. 개인화(Personalization): 언어나 테마 등 사용자의 선호에 따라 맞춤형 서비스를 제공하기 위해
  3. 추적(Tracking): 사용자의 행동을 기록하거나 분석하기 위해

세션 인증 방식에 쿠키를 사용하는 건 이 중 세션 관리에 해당된다. 그럼 쿠키를 사용하여 세션 인증 방식을 구현하기 전에, 쿠키를 설정하는 법부터 알아보자.

쿠키 설정하기

서버가 HTTP 요청을 받으면 응답으로 Set-Cookie 헤더를 하나 이상 보낼 수 있게 된다.
쿠키는 이렇게 이름-값 쌍을 명시하여 설정할 수 있다.
Set-Cookie: <cookie-name>=<cookie-value>

서버는 클라이언트의 요청에 대해 아래와 같이 응답을 보내 해당 쿠키들을 저장하라고 알려줄 수 있다.

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

그럼 브라우저가 해당 쿠키들을 브라우저 저장공간에 저장하고 다음 요청을 보낼 때 저장된 쿠키들을 사용하여 서버에게 아래 형식과 같은 Cookie HTTP 헤더를 전송한다.
Cookie: <cookie-name>=<cookie-value>
이전의 예시에 대해서는 다음과 같은 요청을 보낼 것이다.

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

쿠키를 설정하는 방법도 알아봤으니, 이제 세션 관리 목적으로 쿠키를 사용해 보자.

쿠키를 사용한 세션 인증 방식

쿠키를 사용해서 세션 인증 방식으로 로그인과 로그인(인증)이 필요한 요청을 해보자.

로그인

  1. 사용자가 브라우저의 로그인 창에서 로그인 요청을 보낸다.
  2. 서버는 사용자의 요청을 받고 DB에 해당 사용자가 저장되어 있는지 확인한다.
  3. 세션에 사용자 정보를 저장한다. 서버는 랜덤 String을 만들어 key로 지정하고 value로 사용자 정보를 저장한다.
	{
		'asdfghjkh': {id: "hongildong', name:'홍길동', ... }
	}
  1. 쿠키를 통해 세션의 key를 클라이언트에게 보내준다. 해당 key는 쿠키의 value 값에 저장되며, 쿠키의 key는 세션을 관리하는 주체에 따라 다르다. Django는 sessionid, Tomcat은 JSESSIONID, node.js는 connect.sid라는 이름으로 저장한다.

로그인이 필요한 요청

  1. 사용자가 로그인이 필요한 요청을 한다. 이때 쿠키도 함께 전송한다.

    브라우저가 기본적으로 제공하는 요청 API들은 별도의 옵션 없이는 브라우저의 쿠키와 같은 인증 관련 데이터를 함부로 요청 데이터에 담지 않도록 되어 있다. 그래서 아무 옵션 없이 요청을 하게 되면 CORS 에러가 터진다. (내 얘기다...)
    따라서 fetch를 사용할 경우 헤더에 'credentials': 'include'를 포함하고, axios를 사용할 경우 요청 메서드의 옵션 인자로 넣고 싶으면 { withCredetials: true }를, 전역 설정으로 처리하고 싶다면 axios.defaults.widthCredentials = true;를 사용하면 된다.
    (더 자세한 정보는 아래 글을 참고)
    CORS 쿠키 전송하기

  2. 서버에서 사용자 정보를 확인한다. 쿠키 value 값의 세션 key(=SessionID)가 세션에 저장되어 있는지 확인한다. 저장되어 있을 경우 유효하다고 판단한다.
  3. 만약 유효하다면 해당 요청에 대한 응답을 해준다. 유효하지 않다면 접근 거부 메시지를 보내고 로그인을 요청하는 등의 방식을 사용한다.

위에서 알 수 있듯 SessionID는 브라우저에 쿠키 형태로 저장되어 있지만, 실제 인증 정보는 서버에 저장되어 있기 때문에 이에 따라 세션 인증 방식은 장단점을 갖는다.

세션 인증 방식의 장점

  1. 한 사용자의 디바이스별로 인증을 관리할 수 있다. 여러 디바이스에 접속 중일 때 특정 디바이스의 유저를 로그아웃하게 할 수 있다.
  2. 계정 공유를 관리할 수 있다. 넷플릭스처럼 계정 공유의 수를 제한할 수 있다.
  3. 모든 인증 정보를 서버에서 관리하기 때문에 보안성이 높다. SessionID가 해커에게 탈취되면 해당 세션을 삭제해서 로그아웃 시킬 수 있다.
  4. Cookie 헤더에 SessionID만 실어서 보내면 되므로 트래픽을 적게 사용한다.

세션 인증 방식의 단점

  1. 세션이 서버의 자원을 사용하기 때문에 서버에 부하가 있을 수 있다.
  2. 확장성이 떨어진다. 여러 대의 서버가 요청을 처리할 때, 별도의 작업을 해주지 않는다면 세션 불일치 문제를 겪게 된다.

세션 인증 방식의 많은 장점에도 불구하고 최근 토큰 기반 인증을 많이 사용하는 이유는 세션 인증 방식의 단점인 확장성과 서버의 부담 때문이다. 데이터의 양의 많아질수록 서버에 부담이 가고, 서버를 여러 대로 늘릴 경우 따로 작업을 해주어야하기 때문에 사용자가 많은 애플리케이션이라면 세션 인증 방식보다는 토큰 인증 방식을 사용하는 것이 좋을 것 같다.

이번 프로젝트에서는 3일 동안만 배포할 프로젝트라 세션 인증 방식을 사용했지만, 다음번에 확장 가능성이 있는 프로젝트를 하게 된다면, 토큰 인증 방식을 사용해야겠다.

참고:

0개의 댓글