HTTP 세션은 사용자에 대한 정보를 여러 요청 간에 저장할 수 있는 방법을 제공하며, 특히 MVC 애플리케이션에서 유용합니다.
먼저 필요한 패키지를 설치하세요 (TypeScript 사용자의 경우 해당 패키지의 타입도 설치합니다)
$ npm i express-session
$ npm i -D @types/express-session
설치가 완료되면 express-session 미들웨어를 글로벌 미들웨어로 적용합니다 (예: main.ts 파일에서).
import * as session from 'express-session';
// 초기화 파일 어딘가에서
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: false,
}),
);
Warning!
기본 서버 측 세션 저장소는 프로덕션 환경에는 적합하지 않게 설계되었습니다.
대부분의 상황에서 메모리 누수가 발생하며, 하나의 프로세스를 넘어 확장되지 않으며 주로 디버깅 및 개발용으로 사용됩니다. 자세한 내용은 official repository에서 확인하십시오.
secret
은 세션 ID 쿠키를 서명하는 데 사용됩니다. secret
은 문자열 또는 여러 secret
의 배열일 수 있습니다. 여러 secret
의 배열이 제공된 경우 세션 ID 쿠키의 서명에는 첫 번째 요소만 사용되며, 모든 요소는 요청을 확인할 때 고려됩니다. secret
은 사람에 의해 쉽게 해석되지 않도록하고 가능한 무작위 문자열 세트가 가장 좋습니다.
resave
옵션을 활성화하면 요청 중에 세션이 수정되지 않았더라도 세션을 세션 저장소에 다시 저장하도록 강제합니다. 기본값은 true이지만, 기본값은 미래에 변경될 예정이므로 기본값 사용은 피해야합니다.
마찬가지로 saveUninitialized
옵션을 활성화하면 "uninitialized"된 세션이 세션 저장소에 저장되도록 강제합니다. 세션이 새로운 상태이지만 수정되지 않은 경우 세션이 uninitialized됩니다. false를 선택하면 로그인 세션을 구현하거나 서버 저장소 사용량을 줄이거나 쿠키 설정 전에 허가가 필요한 법률을 준수하는 데 유용합니다. false를 선택하면 세션이 없는 상태에서 클라이언트가 여러 병렬 요청을 만드는 경우의 경쟁 조건에도 도움이 됩니다.
세션 미들웨어에 다른 옵션을 여러 개 전달할 수 있으며, 이에 관한 자세한 내용은 API 문서를 참조하십시오.
Hint!
secure: true
는 권장되는 옵션입니다. 그러나 안전한 쿠키를 위해서는 https로 활성화된 웹사이트가 필요합니다. secure가 설정되고 사이트를 HTTP로 액세스하는 경우 쿠키가 설정되지 않습니다. Node.js를 프록시 뒤에 두고secure: true
를 사용하는 경우 express에서"trust proxy"
를 설정해야합니다.
이렇게 하면 라우트 핸들러 내부에서 세션 값을 설정하고 읽을 수 있습니다.
@Get()
findAll(@Req() request: Request) {
request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
Hint!
@Req()
데코레이터는@nestjs/common
에서 가져옵니다.Request
는express
패키지에서 가져온 것입니다.
또는 다음과 같이 @Session()
데코레이터를 사용하여 요청에서 세션 객체를 추출할 수 있습니다.
@Get()
findAll(@Session() session: Record<string, any>) {
session.visits = session.visits ? session.visits + 1 : 1;
}
Hint!
@Session()
데코레이터는@nestjs/common
패키지에서 가져온 것입니다.
session이란 뭘까?
일정 시간동안 같은 사용자(브라우저)로부터 들어오는
일련의 요구를 하나의 상태로 보고, 그 상태를 일정하게 유지시키는 기술
왜 resave
요청은 나중에는 false를 바꾸려고 하는걸까?
아마 매번 세션에 정보 수정을 요청하는 것이 비효율적이기 때문이다?
trust proxy란?
웹 서버나 애플리케이션에서 사용되는 설정 옵션 중 하나로, 클라이언트 요청의 IP 주소를 어떻게 신뢰할지를 지정하는 역할을 합니다. 주로 프록시 서버나 로드 밸런서를 통해 들어오는 요청을 처리할 때 사용됩니다.
express-session
을 사용해 nest에서 session을 사용할 수 있다.
resave
옵션을 활성화하면 요청 중에 세션이 수정되지 않았더라도 세션을 세션 저장소에 다시 저장하도록 강제한다. 즉 요청이 들어올 때마다 세션을 세션 저장소에 다시 저장한다는 말이다.
trust proxy 설정
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 프록시 서버 뒤에서 실행될 때, 프록시 서버 IP를 신뢰하도록 설정
app.set('trust proxy', true);
await app.listen(3000);
}
bootstrap();
//~~controller.ts
import { Controller, Get, Res } from '@nestjs/common';
import { Response } from 'express';
@Controller()
export class AppController {
@Get()
getHello(@Res() res: Response): void {
// secure: true인 쿠키 설정
res.cookie('myCookie', 'value', { secure: true });
res.send('Cookie set!');
}
}
trust proxy
와 secure: true
를 활용하여 NestJS 애플리케이션 내에서 안전한 쿠키를 다룰 수 있다.
trust proxy 사용 이유
보통 웹 애플리케이션은 클라이언트(브라우저)와 직접 통신하는 것이 아니라, 프록시 서버나 로드 밸런서 등을 통해 중계되는 경우가 많다. 이런 경우 클라이언트의 실제 IP 주소를 확인하는 것이 어려울 수 있다.
프록시 서버를 거칠 때 IP 주소가 변경될 수 있음: 클라이언트의 요청은 프록시 서버를 통해 애플리케이션 서버로 전달된다. 프록시 서버를 거치면서 클라이언트의 IP 주소가 변경될 수 있다. 따라서 애플리케이션 서버가 실제 클라이언트의 IP 주소를 정확히 식별하려면 프록시 서버의 IP를 신뢰해야 한다.
보안과 신뢰성 확보: secure: true 옵션을 가진 쿠키는 HTTPS로 통신할 때만 전송된다. 프록시 서버를 통해 HTTPS 연결이 중개되는 경우, 애플리케이션 서버는 프록시 서버가 신뢰할 수 있는지 확인해야한다. 그렇지 않으면 보안에 취약한 상태가 될 수 있다.
쿠키와 세션의 차이
쿠키(Cookie) | 세션(Session) | |
---|---|---|
저장 위치 | 클라이언트(=접속자 PC) | 웹 서버 |
저장 형식 | text | Object |
만료 시점 | 쿠키 저장시 설정 | 브라우저 종료시 삭제 |
사용하는 자원(리소스) | 클라이언트 리소스 | 웹 서버 리소스 |
용량 제한 | 총 300개, 하나의 도메인 당 20개, 하나의 쿠키 당 4KB(=4096byte) | 서버가 허용하는 한 용량 제한 없음 |
속도 | 세션보다 빠름 | 쿠키보다 느림 |
보안 | 세션보다 안좋음 | 쿠키보다 좋음 |
보안이 안좋은데 쿠키를 사용하는 이유는 크게 세션이 사용하는 자원이 웹 서버 리소스라는 점에 있다.