intermediate 14 min read

Security & CORS

Secure your Fastify application with CORS, Helmet, rate limiting, and more.

Security Plugins

const Fastify = require('fastify');\n\nconst app = Fastify({ logger: true });\n\n// CORS\nawait app.register(require('@fastify/cors'), {\n  origin: ['https://yourdomain.com'],\n  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],\n  allowedHeaders: ['Content-Type', 'Authorization'],\n  credentials: true,\n  maxAge: 86400,\n});\n\n// Rate limiting\nawait app.register(require('@fastify/rate-limit'), {\n  max: 100,\n  timeWindow: '1 minute',\n  keyGenerator: (request) => {\n    return request.headers['x-forwarded-for'] || request.ip;\n  },\n  errorResponseBuilder: (request, context) => ({\n    statusCode: 429,\n    error: 'Too Many Requests',\n    message: `Rate limit exceeded. Retry after ${context.after}`,\n    retryAfter: context.after,\n  }),\n});\n\n// Helmet (security headers)\nawait app.register(require('@fastify/helmet'), {\n  contentSecurityPolicy: {\n    directives: {\n      defaultSrc: ["'self'"],\n      scriptSrc: ["'self'", "'unsafe-inline'"],\n    },\n  },\n});\n\n// CSRF protection\nawait app.register(require('@fastify/csrf-protection'), {\n  cookieOpts: {\n    sameSite: 'strict',\n    httpOnly: true,\n  },\n});

Environment Configuration

const app = Fastify({\n  logger: {\n    level: process.env.LOG_LEVEL || 'info',\n  },\n});\n\n// Validate required env vars before starting\nconst required = ['JWT_SECRET', 'DATABASE_URL'];\nfor (const key of required) {\n  if (!process.env[key]) {\n    app.log.error(`Missing required env var: \${key}`);\n    process.exit(1);\n  }\n}

Examples

const Fastify = require('fastify');

async function buildSecureApp() {
  const app = Fastify({ logger: true });

  // Security plugins
  await app.register(require('@fastify/cors'), {
    origin: process.env.CORS_ORIGIN?.split(',') || true,
  });

  await app.register(require('@fastify/rate-limit'), {
    max: 100,
    timeWindow: '1 minute',
  });

  await app.register(require('@fastify/helmet'));

  // Sensitive data endpoint
  app.get('/api/users', async (request) => ({
    data: [
      { id: 1, name: 'Alice', email: '[email protected]' },
    ],
  }));

  // Graceful shutdown
  const signals = ['SIGINT', 'SIGTERM'];
  for (const signal of signals) {
    process.on(signal, async () => {
      await app.close();
      process.exit(0);
    });
  }

  return app;
}

buildSecureApp()
  .then(app => app.listen({ port: 3000 }))
  .catch(err => {
    console.error(err);
    process.exit(1);
  });

Your Notes

Sign in to take notes for this lesson.

Quiz

Authentication & Authorization Quiz

0 questions

Sign in to take quiz

Discussion

Sign in to join the discussion.

Flashcards

Sign in to create flashcards.