Restify CORS Middleware 2
raw JSON →restify-cors-middleware2 is a specialized CORS (Cross-Origin Resource Sharing) middleware designed for use with Restify servers, providing full compliance with the W3C CORS specification. The package, currently at version 2.2.1, offers robust features for handling preflight requests and actual requests, with advanced capabilities for defining allowed origins using strings, wildcards, and regular expressions. A key differentiator is its enhanced security posture, where it dynamically sets the `Access-Control-Allow-Origin` header to the matching origin, rather than a broad wildcard, preventing information leakage about other supported domains. It also clearly documents potential security implications of using `origins: ['*']`. This middleware is a successor to an earlier `restify-cors-middleware` package, indicating updates and potential breaking changes from its predecessor. It includes TypeScript declaration files, facilitating its use in TypeScript projects. The release cadence is moderate, with stable versions released as needed for feature enhancements and bug fixes.
Common errors
error Access to XMLHttpRequest at 'http://api.example.com/data' from origin 'http://client.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ↓
http://client.example.com) is explicitly listed in the origins array of the corsMiddleware options, or use a wildcard/regex that matches it if appropriate for your security model. error Failed to load resource: Preflight response for URL 'http://api.example.com/data' is invalid. HTTP status code 405. ↓
server.pre(cors.preflight) is called before any other routes or middleware that might prematurely handle or block OPTIONS requests. Ensure the preflightMaxAge is set appropriately. error Response to preflight request doesn't pass access control check: It does not have HTTP ok status. ↓
cors.preflight middleware and that no other middleware is interfering or returning an error status for preflight requests. Warnings
breaking This package, `restify-cors-middleware2`, is a successor or fork of an older `restify-cors-middleware` package. There are likely breaking changes in API and behavior compared to the original, necessitating careful migration if upgrading from the older version. ↓
gotcha Using `origins: ['*']` allows all origins, but this comes with significant security implications. Additionally, enabling `allowCredentialsAllOrigins` with `*` can be a security risk. ↓
gotcha CORS headers are not sent for requests that do not include an `Origin` header, as per the W3C spec. This can be a source of confusion for developers expecting CORS headers on all requests. ↓
gotcha Caching layers (reverse proxies, CDNs) must be configured to vary their cache based on the `Origin` header. Failing to do so can lead to incorrect CORS headers being served to clients, potentially exposing data or causing unexpected behavior. ↓
gotcha The TypeScript declaration file is noted as 'basic' and 'not validated' by the package maintainers, who don't use TypeScript locally. This means the types might not be fully accurate or comprehensive. ↓
Install
npm install restify-cors-middleware2 yarn add restify-cors-middleware2 pnpm add restify-cors-middleware2 Imports
- corsMiddleware
const corsMiddleware = require('restify-cors-middleware2'); - corsMiddleware wrong
import { corsMiddleware } from 'restify-cors-middleware2';correctimport corsMiddleware from 'restify-cors-middleware2'; - CorsOptions wrong
import { CorsOptions } from 'restify-cors-middleware2';correctimport type { CorsOptions } from 'restify-cors-middleware2';
Quickstart
const restify = require('restify');
const corsMiddleware = require('restify-cors-middleware2');
const server = restify.createServer({
name: 'my-cors-server',
});
const cors = corsMiddleware({
preflightMaxAge: 5, // Cache preflight response for 5 seconds
origins: ['http://localhost:3000', /localhost:\d+$/], // Allow specific origins, including regex
allowHeaders: ['API-Token', 'Authorization', 'Content-Type'], // Custom headers to allow
exposeHeaders: ['API-Token-Expiry', 'X-Custom-Header'] // Headers to expose to the client
});
server.pre(cors.preflight);
server.use(cors.actual);
// Example route
server.get('/hello', (req, res, next) => {
res.send({ message: 'Hello from Restify!' });
return next();
});
server.listen(8080, () => {
console.log('%s listening at %s', server.name, server.url);
});