백엔드를 어느정도 공부해 본 사람이라면, 웹 서버를 구축해 본 경험은 당연히 있을 것이고 그렇다면 HTTP
방식을 사용하여 클라이언트와 서버가 서로 요청/응답
을 공유한다는 사실 또한 알고 있을 것이다.
이 때, HTTP
의 특징으로 서버와 클라이언트는 Stateless
를 유지하게 되고 이 상황에서 지속적으로 서로 가지고 있어야 할 정보(즉, 사용자 인증 및 인가 정보 및 기타)들은 매 통신마다 전달해야 하기 때문에 Session과 Cookie 또는 Token과 같은 기술들이 등장하게 되었다.
여기서 HTTP의 Stateless란 클라이언트에서 전달 받은 요청에 대한 응답만 처리한다는 뜻으로 그 외 요청에 대한 기록이라던지 응답에 대한 후속 조치 하지 않는 것이다.
HTTP에 대한 서론은 여기까지만 진행하는 것으로 하고 본격적으로 Session, Cookie 그리고 Token에 알아보자.
우선 Session
과 Cookie
는 서로 다른 개념이지만 Session Based Authentication
을 진행 할 때 두 가지 개념 전부 적용하는 사례가 많기 때문에 여기에서는 두 가지 전부 사용하여 인증을 진행한다는 가정 하에 이야기를 해보려고 한다.
동일한 클라이언트(사용자)가 브라우저를 통해 웹 서버에 접속한 시점으로부터 브라우저를 종료하여 연결을 끝내는 시점 동안에 들어오는 일련의 Request를 하나의 상태로 보고, 그 상태를 일정하게 유지하여 클라이언트와 웹 서버가 논리적으로 연결된 상태를 뜻합니다.
Cookie는 클라이언트의 컴퓨터에 저장되는 데이터 파일입니다. Cookie에는 이름, 값, 만료 날짜/시간(저장기간), 경로 정보 등으로 구성이 되어있습니다.
Session-Cookie Authentication
절차는 다음과 같다.
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은 제한된 리소스에 대해 일정 기간 동안 접근 할 수 있는 권한을 캡슐화 한 것입니다
const login = async (email, password) => {
//general logic//
return jwt.sign({ userId: user.id }, 'secret-key');
};
우선 토큰을 만들어 주는 방법은 간단하다. jwt 패키지를 인스톨 후, jwt.sign()을 사용하여 토큰을 만들어 주면 된다.
물론 jwt 패키지를 공부하여 추 후에 jwt를 분해하는 방법도 공부 한 후 Verification을 요청 때 받은 Token을 분해하여 진행해야 하는 것도 잊으면 안된다.
Session-Cookie와 Token 인증 방식 중 뭘 하나 택하라고 하면 바로 결정을 하지는 못할 것 같다. 둘의 장단점이 너무나 명확하기 때문이다. 그렇기에 서비스를 기획할때 기획에 맞게 설정할 방법이 있다. 혹자는 TOKEN과 COOKIE를 결합해서 쓰기도 한다. 추후 기회가 된다면 보안성을 전문적으로 다뤄 좀 더 이 글을 보완해보고 싶다.