☰ 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ữ
Bảo mật (Security)

Helmet

Bản dịch từ docs.nestjs.com/security/helmet

Helmet có thể giúp bảo vệ app của bạn khỏi một số lỗ hổng web đã được biết đến, bằng cách thiết lập các HTTP header phù hợp. Về cơ bản, Helmet chỉ là một tập hợp các middleware function nhỏ, mỗi function thiết lập một HTTP header liên quan đến bảo mật (đọc thêm).

Gợi ý Lưu ý rằng việc áp dụng helmet như global middleware hoặc đăng ký nó phải được thực hiện trước các lệnh gọi app.use() khác hoặc các hàm setup có thể gọi app.use(). Điều này là do cách nền tảng bên dưới (tức Express hoặc Fastify) hoạt động, nơi thứ tự khai báo middleware/route có ý nghĩa quan trọng. Nếu bạn dùng middleware như helmet hay cors sau khi đã khai báo một route, middleware đó sẽ không áp dụng cho route đó, nó chỉ áp dụng cho các route được khai báo sau middleware.

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

Bắt đầu bằng việc cài package cần thiết.

$ npm i --save helmet

Sau khi cài xong, áp dụng nó như một global middleware.

import helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());

Cảnh báo Khi dùng helmet, @apollo/server (4.x), và Apollo Sandbox, có thể xảy ra vấn đề với CSP (Content Security Policy) trên Apollo Sandbox. Để giải quyết vấn đề này, hãy cấu hình CSP như dưới đây:

app.use(helmet({
  crossOriginEmbedderPolicy: false,
  contentSecurityPolicy: {
    directives: {
      imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
      scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
      manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
      frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
    },
  },
}));

Dùng với Fastify

Nếu bạn dùng FastifyAdapter, cài package @fastify/helmet:

$ npm i --save @fastify/helmet

fastify-helmet không nên được dùng như một middleware, mà nên dùng như một Fastify plugin, tức là thông qua app.register():

import helmet from '@fastify/helmet'
// somewhere in your initialization file
await app.register(helmet)

Cảnh báo Khi dùng apollo-server-fastify và @fastify/helmet, có thể xảy ra vấn đề với CSP trên GraphQL playground, để giải quyết xung đột này, hãy cấu hình CSP như dưới đây:

await app.register(fastifyHelmet, {
   contentSecurityPolicy: {
     directives: {
       defaultSrc: [`'self'`, 'unpkg.com'],
       styleSrc: [
         `'self'`,
         `'unsafe-inline'`,
         'cdn.jsdelivr.net',
         'fonts.googleapis.com',
         'unpkg.com',
       ],
       fontSrc: [`'self'`, 'fonts.gstatic.com', 'data:'],
       imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
       scriptSrc: [
         `'self'`,
         `https: 'unsafe-inline'`,
         `cdn.jsdelivr.net`,
         `'unsafe-eval'`,
       ],
     },
   },
 });

// If you are not going to use CSP at all, you can use this:
await app.register(fastifyHelmet, {
  contentSecurityPolicy: false,
});

Ghi chú người dịch helmet thực chất chỉ là một chuỗi middleware Express được ghép sẵn — tương đương việc bạn tự viết vài dòng res.setHeader(...) cho từng header như X-Content-Type-Options, Strict-Transport-Security, X-Frame-Options trong một middleware Express hoặc Laravel thủ công. Lưu ý quan trọng nhất khi vibe-code: nếu bạn gọi app.use(helmet()) sau khi đã khai báo route (hoặc sau middleware khác đã trả response), header sẽ không được áp cho các route khai báo trước đó — đây là lỗi thứ tự middleware rất dễ mắc, không phải lỗi của helmet.

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.