Skip to content

CORS Configuration

PGRestify provides comprehensive Cross-Origin Resource Sharing (CORS) configuration to secure and manage cross-origin requests.

Basic CORS Setup

typescript
import { createClient } from '@webcoded/pgrestify';

const client = createClient('http://localhost:3000', {
  cors: {
    // Enable CORS with default settings
    enabled: true
  }
});

Detailed CORS Configuration

typescript
const client = createClient('http://localhost:3000', {
  cors: {
    // Allowed origins
    origins: [
      'https://myapp.com',
      'http://localhost:3000',
      'https://staging.myapp.com'
    ],

    // HTTP methods allowed
    methods: [
      'GET', 
      'POST', 
      'PUT', 
      'DELETE', 
      'PATCH', 
      'OPTIONS'
    ],

    // Allow credentials (cookies, authorization headers)
    credentials: true,

    // Allowed headers
    headers: [
      'Content-Type', 
      'Authorization', 
      'X-Requested-With'
    ],

    // Headers exposed to the browser
    exposedHeaders: [
      'Content-Range', 
      'X-Content-Range'
    ],

    // How long preflight request can be cached
    maxAge: 86400 // 24 hours
  }
});

Dynamic Origin Validation

typescript
const client = createClient('http://localhost:3000', {
  cors: {
    // Dynamic origin validation function
    origins: (origin) => {
      // Custom origin validation logic
      const allowedDomains = [
        'https://myapp.com',
        'http://localhost:3000'
      ];

      return allowedDomains.includes(origin) || 
             origin?.endsWith('.myapp.com');
    }
  }
});

Environment-Based Configuration

typescript
const client = createClient('http://localhost:3000', {
  cors: {
    origins: process.env.NODE_ENV === 'production'
      ? ['https://myapp.com', 'https://api.myapp.com']
      : ['http://localhost:3000', 'http://localhost:3001']
  }
});

Strict Security Configuration

typescript
const client = createClient('http://localhost:3000', {
  cors: {
    // Highly restrictive CORS settings
    origins: ['https://myapp.com'],
    methods: ['GET', 'POST'],
    credentials: false,
    headers: ['Content-Type'],
    
    // Additional security options
    strictOriginCheck: true,
    blockUnsafeOrigins: true
  }
});

Handling Preflight Requests

typescript
// Automatic preflight request handling
const client = createClient('http://localhost:3000', {
  cors: {
    // Customize preflight response
    preflight: {
      // Custom headers for preflight
      additionalHeaders: {
        'X-Preflight-Validated': 'true'
      },
      
      // Custom status code
      statusCode: 200
    }
  }
});

Logging and Monitoring

typescript
const client = createClient('http://localhost:3000', {
  cors: {
    // Log CORS-related events
    logging: {
      enabled: true,
      level: 'warn',
      
      // Custom logging handler
      handler: (event) => {
        switch (event.type) {
          case 'origin_blocked':
            console.warn(`Blocked origin: ${event.origin}`);
            break;
          case 'preflight_request':
            console.log(`Preflight from: ${event.origin}`);
            break;
        }
      }
    }
  }
});

Error Handling

typescript
try {
  const data = await client
    .from('users')
    .select('*')
    .execute();
} catch (error) {
  if (error.name === 'CORSError') {
    // Handle CORS-related errors
    console.error('CORS configuration error:', error.message);
    
    // Potential recovery or fallback mechanism
    fallbackToDefaultCORS();
  }
}

Best Practices

  • Be as specific as possible with allowed origins
  • Use environment-based configuration
  • Implement dynamic origin validation
  • Limit allowed methods and headers
  • Enable credentials only when necessary
  • Log and monitor CORS-related events
  • Regularly review and update CORS settings

Security Considerations

  • Never use wildcard * in production
  • Validate and sanitize origins
  • Use HTTPS for all production origins
  • Implement additional authentication layers
  • Rotate and update allowed origins
  • Monitor for potential CORS misconfigurations

Performance Implications

  • CORS checks add minimal overhead
  • Caching preflight requests reduces latency
  • Use efficient origin validation functions
  • Minimize the number of allowed origins
  • Consider using a CDN or reverse proxy for advanced CORS management

Framework-Specific Notes

Next.js

typescript
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Origin', value: 'https://myapp.com' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE' }
        ]
      }
    ];
  }
};

Express.js

typescript
import cors from 'cors';
import express from 'express';

const app = express();

app.use(cors({
  origin: 'https://myapp.com',
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

Troubleshooting

  • Check browser console for CORS errors
  • Verify server and client configurations match
  • Ensure all origins use consistent protocols
  • Validate headers and methods
  • Test with different browsers and environments

Released under the MIT License.