백엔드를 어느정도 공부해 본 사람이라면, 웹 서버를 구축해 본 경험은 당연히 있을 것이고 그렇다면 HTTP 방식을 사용하여 클라이언트와 서버가 서로 요청/응답을 공유한다는 사실 또한 알고 있을 것이다.
이 때, HTTP 의 특징으로 서버와 클라이언트는 Stateless를 유지하게 되고 이 상황에서 지속적으로 서로 가지고 있어야 할 정보(즉, 사용자 인증 및 인가 정보 및 기타)들은 매 통신마다 전달해야 하기 때문에 Session과 Cookie 또는 Token과 같은 기술들이 등장하게 되었다.
여기서 HTTP의 Stateless란 클라이언트에서 전달 받은 요청에 대한 응답만 처리한다는 뜻으로 그 외 요청에 대한 기록이라던지 응답에 대한 후속 조치 하지 않는 것이다.
HTTP에 대한 서론은 여기까지만 진행하는 것으로 하고 본격적으로 Session, Cookie 그리고 Token에 알아보자.
✍ Session & Cookie
우선 Session과 Cookie는 서로 다른 개념이지만 Session Based Authentication을 진행 할 때 두 가지 개념 전부 적용하는 사례가 많기 때문에 여기에서는 두 가지 전부 사용하여 인증을 진행한다는 가정 하에 이야기를 해보려고 한다.
📝 Session이란..
동일한 클라이언트(사용자)가 브라우저를 통해 웹 서버에 접속한 시점으로부터 브라우저를 종료하여 연결을 끝내는 시점 동안에 들어오는 일련의 Request를 하나의 상태로 보고, 그 상태를 일정하게 유지하여 클라이언트와 웹 서버가 논리적으로 연결된 상태를 뜻합니다.
Session의 특징
- 서버 측 저장 : 다양한 요청이 오가는 환경에서도 인증 정보를 유지하기 위해 서버 쪽에 필요 정보가 저장된다.
- 고유 세션 ID : 각 각의 유저는 고유한 세션 ID를 부여 받게 되고, 이 ID를 클라인트가 서버로 전달하면서 ID에 따른 정보를 클라이언트에 전달 해 줄 수 있다.
- Stateful : Http가 Stateless 상황임에도 불구하고 세션에 특정 유저의 정보가 남아 있는 한 유저가 웹사이트를 일시적으로 나갔다 들어와도 정보는 살아 있다.
- 동적 데이터 : 세션에 저장되어 있는 데이터는 클라이언트에서 활동한 유저의 행동에 따라 동적이게 변한다.
- 커스텀 용이 : 세션에 저장되어질 정보들은 서비스 기획에 따라 손쉽게 편집이 가능하다.
📝 Cookie란..
Cookie는 클라이언트의 컴퓨터에 저장되는 데이터 파일입니다. Cookie에는 이름, 값, 만료 날짜/시간(저장기간), 경로 정보 등으로 구성이 되어있습니다.
Cookie의 특징
- 클라이언트 측 저장 : 유저가 사용하는 웹 브라우저의 로컬 스토리지에 저장이되며 서버에 요청을 보낼 때 마다 같이 보내진다.
- Stateful : 유저가 웹 브라우저는 닫았음에도 쿠키가 유지되게끔 설정 할 수 있기에 특정 정보를 유지하는게 가능하다.
- 적은 용량 : 쿠키는 위에서 언급한 대로 약 4kB의 용량을 가지고 있기에 작은 양의 정보를 담는데 적합하다.
- 보안성 : 저장된 데이터의 접근을 막기 위해 암호화 및 추가 기술을 이용하여 보안성을 높일 수 있다.
- 도메인 간 지원 : 쿠키는 다양한 도메인에 공유가 가능하다.
📝 Session-Cookie Authentication Flow
Session-Cookie Authentication 절차는 다음과 같다.

- 인증 정보를 서버측에 전달
- 인증이 완료 되면, 사용자의 정보를 Session에 저장 후 서버의 메모리 할당 한 뒤 Session ID 발급
- Session ID를 Cookie에 저장 후 Header에 담아 클라이언트에 전달
- 클라이언트는 응답으로 받은 Cookie를 브라우저에 저장 후 매 요청 시 같이 전달
- 클라이언트로부터 요청을 받았을 때 받은 Cookie의 Session ID를 분석하여 Verification 진행
📝 Session-Cookie Authn의 장/단점
장점
- 사용 방법 용이
- Stateful 데이터
- 필요에 따른 수정에 용이
단점
- 서버 측 저장으로 인해 발생하는 리소스 낭비
- Session ID가 중간에 가로채질 경우 보안에 취약
- 웹 사이트의 요청 및 유저 수의 증가에 따라 세션 관리 난이도 상승
- Cookie 내부에 Session ID가 저장됨에 따라 Session에 저장 될 데이터가 한정적
📝 Session-Cookie Authn on ExpressJS
const express = require("express");
const session = require("express-session");
const app = express();
app.use(session({
secret: "secret-key",
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
},
}));
Session-Cookie방식을 채택할 경우, 위에 방식처럼 Config를 잡아 놓고 인증 로직을 구현해 주면 된다.
Cookie에 httpOnly 설정 값을 true로 설정을 해주어 Http protocol에서만 Cookie가 접근 가능하도록 설정을 해야 보안성이 올라간다.
✍ Token
📝 Token이란..
Token은 제한된 리소스에 대해 일정 기간 동안 접근 할 수 있는 권한을 캡슐화 한 것입니다
Token의 특징
- Stateless : Session-Cookie와는 다르게 토큰은 Full Stateless이다
- Compact : Token은 Session 보다 작아 Http 요청에 용이하다.
- Self-Contained : Token 내부에 유저의 정보가 일부 담겨있기 때문에, 서버가 유저 정보를 바로 캐치 할 수 있다.
- 보안성 : 암호화가 잘 되어 있다.
📝 Token Based Authentication Flow

- 인증 정보를 서버측에 전달
- JSON Web Token 패키지를 다운 받은 후 Token은 생성하여 로그인이 성공된 유저에게 토큰을 전달
- 유저는 매 요청 시 마다 Token은 서버 측에 전달
- Token을 분해 후 유저 Verification 진행
📝 Token Authn의 장/단점
장점 (특징과 동일하기에 키워드만 적고 넘어가겠다).
- Stateless
- Compact
- Self-Contained
- 보안성
단점
- 다른 방식에 비해 복잡할 수 있다 (필자는..잘 모르겠다).
- 클라이언트 측 (로컬 스토리지)에 일반적으로 저장하기 때문에 강탈에 취약 할 수 있다.
- 브라우저 간 호환성 문제가 발생 할 수 있다.
- 다른 인증 방식에 비해 성능 문제가 있을 수 있다.
📝 Token Authn on ExpressJS
const login = async (email, password) => {
return jwt.sign({ userId: user.id }, 'secret-key');
};
우선 토큰을 만들어 주는 방법은 간단하다. jwt 패키지를 인스톨 후, jwt.sign()을 사용하여 토큰을 만들어 주면 된다.
물론 jwt 패키지를 공부하여 추 후에 jwt를 분해하는 방법도 공부 한 후 Verification을 요청 때 받은 Token을 분해하여 진행해야 하는 것도 잊으면 안된다.
Session-Cookie와 Token 인증 방식 중 뭘 하나 택하라고 하면 바로 결정을 하지는 못할 것 같다. 둘의 장단점이 너무나 명확하기 때문이다. 그렇기에 서비스를 기획할때 기획에 맞게 설정할 방법이 있다. 혹자는 TOKEN과 COOKIE를 결합해서 쓰기도 한다. 추후 기회가 된다면 보안성을 전문적으로 다뤄 좀 더 이 글을 보완해보고 싶다.