☰ Mục lục series
Tài liệu NestJS tiếng Việt
  1. Nhập môn (Overview)
    1. Giới thiệu
    2. First steps
    3. Controllers
    4. Providers
    5. Modules
    6. Middleware
    7. Exception filters
    8. Pipes
    9. Guards
    10. Interceptors
    11. Custom decorators
  2. Nền tảng (Fundamentals)
    1. Custom providers
    2. Asynchronous providers
    3. Dynamic modules
    4. Injection scopes
    5. Circular dependency
    6. Module reference
    7. Lazy-loading modules
    8. Execution context
    9. Lifecycle events
    10. Discovery service
    11. Platform agnosticism
    12. Testing
  3. Kỹ thuật (Techniques)
    1. Configuration
    2. Database (SQL)
    3. MongoDB
    4. Validation
    5. Caching
    6. Serialization
    7. Versioning
    8. Task scheduling
    9. Queues
    10. Logging
    11. Cookies
    12. Events
    13. Compression
    14. File upload
    15. Streaming files
    16. HTTP module
    17. Session
    18. MVC
    19. Performance (Fastify)
    20. Server-Sent Events
  4. Bảo mật (Security)
    1. Authentication
    2. Authorization
    3. Encryption & Hashing
    4. Helmet
    5. CORS
    6. CSRF
    7. Rate limiting
    8. Vòng đời request
  5. OpenAPI (Swagger)
    1. Introduction
    2. Types and parameters
    3. Operations
    4. Security
    5. Mapped types
    6. Decorators
    7. CLI plugin
    8. Other features
  6. Recipes
    1. REPL
    2. CRUD generator
    3. SWC (fast compiler)
    4. Passport (auth)
    5. Hot reload
    6. MikroORM
    7. Router module
    8. Health checks (Terminus)
    9. CQRS
    10. Prisma
    11. Serve static
    12. Commander
    13. Async local storage
  7. WebSockets
    1. Gateways
    2. Exception filters
    3. Pipes
    4. Guards
    5. Interceptors
    6. Adapters
  8. Microservices
    1. Overview
    2. Redis
    3. MQTT
    4. NATS
    5. RabbitMQ
    6. Kafka
    7. gRPC
    8. Custom transporters
    9. Exception filters
    10. Pipes
    11. Pre-request hooks
    12. Guards
    13. Interceptors
  9. GraphQL
    1. Quick start
    2. Resolvers
    3. Mutations
    4. Subscriptions
    5. Scalars
    6. Directives
    7. Interfaces
    8. Unions and enums
    9. Field middleware
    10. Mapped types
    11. Plugins
    12. Complexity
    13. Extensions
    14. CLI plugin
    15. Generating SDL
    16. Sharing models
    17. Other features
    18. Federation
  10. CLI & triển khai
    1. CLI overview
    2. Workspaces
    3. Libraries
    4. Usage
    5. Scripts
    6. Deployment
    7. Standalone apps
  11. FAQ
    1. Serverless
    2. HTTP adapter
    3. Keep-Alive connections
    4. Global path prefix
    5. Raw body
    6. Hybrid application
    7. HTTPS & multiple servers
    8. Common errors
  12. Phụ lục
    1. Bảng thuật ngữ
Kỹ thuật (Techniques)

Session

Bản dịch từ docs.nestjs.com/techniques/session

HTTP session cung cấp cách lưu thông tin về user qua nhiều request khác nhau, đặc biệt hữu ích cho ứng dụng MVC.

Dùng với Express (mặc định)

Đầu tiên, cài package cần thiết (và type của nó cho người dùng TypeScript):

$ npm i express-session
$ npm i -D @types/express-session

Sau khi cài đặt xong, áp dụng middleware express-session như một middleware global (ví dụ, trong file main.ts của bạn).

import session from 'express-session';
// đặt ở đâu đó trong file khởi tạo (initialization) của bạn
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);

Cảnh báo Cơ chế lưu session phía server mặc định (default server-side session storage) có chủ đích không được thiết kế cho môi trường production. Nó sẽ leak memory (rò bộ nhớ) trong hầu hết các trường hợp, không scale được quá một process, và chỉ dùng để debug và phát triển. Đọc thêm ở repository chính thức.

secret được dùng để ký (sign) session ID cookie. Giá trị này có thể là một string cho một secret duy nhất, hoặc một array chứa nhiều secret. Nếu bạn cung cấp một array secret, chỉ phần tử đầu tiên được dùng để ký session ID cookie, còn tất cả các phần tử sẽ được xem xét khi verify chữ ký trong các request. Secret bản thân nó nên khó bị con người đoán ra, tốt nhất nên là một tập ký tự ngẫu nhiên.

Bật option resave sẽ buộc session phải được lưu lại (save back) vào session store, ngay cả khi session không hề bị thay đổi trong suốt request đó. Giá trị mặc định là true, nhưng dùng mặc định này đã bị deprecated (không còn khuyến nghị), vì giá trị mặc định sẽ thay đổi trong tương lai.

Tương tự, bật option saveUninitialized sẽ buộc một session đang “chưa được khởi tạo” (uninitialized) phải được lưu vào store. Một session được coi là uninitialized khi nó mới được tạo nhưng chưa bị thay đổi. Chọn false hữu ích khi implement session đăng nhập, giảm dung lượng lưu trữ ở server, hoặc để tuân thủ các luật yêu cầu phải có sự cho phép trước khi set cookie. Chọn false cũng giúp tránh race condition khi client gửi nhiều request song song mà chưa có session (nguồn).

Bạn có thể truyền nhiều option khác cho middleware session, đọc thêm về chúng trong tài liệu API.

Gợi ý Xin lưu ý rằng secure: true là option được khuyến nghị. Tuy nhiên, nó yêu cầu website phải hỗ trợ https, nghĩa là HTTPS là bắt buộc để dùng cookie secure. Nếu secure được set, mà bạn truy cập site qua HTTP, cookie sẽ không được set. Nếu node.js của bạn nằm sau một proxy và bạn dùng secure: true, bạn cần set "trust proxy" trong express.

Với những cài đặt trên, bây giờ bạn có thể set và đọc giá trị session ngay trong route handler, như sau:

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}

Gợi ý Decorator @Req() được import từ @nestjs/common, còn Request được import từ package express.

Ngoài ra, bạn có thể dùng decorator @Session() để lấy session object ra từ request, như sau:

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}

Gợi ý Decorator @Session() được import từ package @nestjs/common.

Ghi chú người dịch Nếu bạn từng dùng express-session thuần với Express trước khi biết Nest, cơ chế session ở đây hoàn toàn giống nhau — Nest không thêm layer trừu tượng nào cho session cả, chỉ cung cấp decorator @Session() như một “shortcut” thay cho request.session. Đây khác với Laravel, nơi session được tích hợp sẵn vào framework và tự động lưu vào driver bạn chọn (file, redis, database) — với Nest bạn phải tự chọn và cấu hình express-session (hoặc tương đương ở Fastify) như một thư viện bên thứ ba.

Dùng với Fastify

Đầu tiên, cài package cần thiết:

$ npm i @fastify/secure-session

Sau khi cài đặt xong, register plugin fastify-secure-session:

import secureSession from '@fastify/secure-session';

// đặt ở đâu đó trong file khởi tạo (initialization) của bạn
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});

Gợi ý Bạn cũng có thể tạo trước (pregenerate) một key (xem hướng dẫn) hoặc dùng key rotation.

Đọc thêm về các option khả dụng trong repository chính thức.

Với những cài đặt trên, bây giờ bạn có thể set và đọc giá trị session ngay trong route handler, như sau:

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}

Ngoài ra, bạn có thể dùng decorator @Session() để lấy session object ra từ request, như sau:

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}

Gợi ý Decorator @Session() được import từ @nestjs/common, còn secureSession.Session được import từ package @fastify/secure-session (câu import: import * as secureSession from '@fastify/secure-session').

Nội dung gốc: NestJS Documentation © Kamil Myśliwiec, giấy phép MIT. Bản dịch và ghi chú: Lê Văn Dũng.