cors Node.js middleware

repository·master·Indexed 27 days ago

https://github.com/expressjs/cors

Node.js CORS middleware for Express and Connect that sets CORS response headers to instruct browsers on which origins are permitted to read responses from a server. Version 2.8.6 supports static and dynamic origin validation, pre-flight request handling, and customizable configuration options including origin, methods, credentials, and allowed headers.

Tokens
3.9K
Snippets
8
Records
12
Agent score
42%

What's inside cors

  1. Enable CORS Pre-Flight requests

    master

    For 'complex' requests (e.g., using DELETE or custom headers), browsers send an OPTIONS pre-flight request. You must add an OPTIONS handler for the route to support this. Alternatively, you can enable pre-flighting across-the-board by adding app.options('*', cors()) before other routes. Note that using app.use(cors()) as application-level middleware handles pre-flight requests automatically for all routes.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    
    app.options('/products/:id', cors()) // preflight for DELETE
    app.delete('/products/:id', cors(), function (req, res, next) {
      res.json({msg: 'Hello'})
    })
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  2. Understand CORS misconceptions

    master

    It is important to understand what CORS does and does not do:

    • CORS does not block requests from disallowed origins: Your server receives and processes every request. CORS headers tell the browser whether JavaScript can read the response—not whether the request is allowed.
    • CORS is not access control: It does not protect your API from unauthorized access. Any HTTP client (curl, Postman, another server) can call your API regardless of CORS settings. Use authentication and authorization to protect your API.
    • Setting a specific origin does not restrict server access: Setting origin: 'http://example.com' means browsers will only let JavaScript from that origin read responses. The server still responds to all requests.
  3. Configure CORS with static options

    master

    Pass an options object to cors() to configure specific headers like origin and optionsSuccessStatus. This is useful for restricting access to specific domains or supporting legacy browsers.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    
    var corsOptions = {
      origin: 'http://example.com',
      optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
    }
    
    // Adds headers: Access-Control-Allow-Origin: http://example.com, Vary: Origin
    app.get('/products/:id', cors(corsOptions), function (req, res, next) {
      res.json({msg: 'Hello'})
    })
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  4. Configure CORS with dynamic origin validation

    master

    To validate origins dynamically (e.g., from a database), set the origin option to a function. This function receives the request origin and a callback with the signature callback(error, origin). The origin passed to the callback can be any valid value allowed by the origin option except for another function.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    
    var corsOptions = {
      origin: function (origin, callback) {
        // db.loadOrigins is an example call to load
        // a list of origins from a backing database
        db.loadOrigins(function (error, origins) {
          callback(error, origins)
        })
      }
    }
    
    // Adds headers: Access-Control-Allow-Origin: <matched origin>, Vary: Origin
    app.get('/products/:id', cors(corsOptions), function (req, res, next) {
      res.json({msg: 'Hello'})
    })
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  5. Enable CORS for all requests

    master

    To enable CORS for all incoming requests in your Express application, use cors() as application-level middleware. This adds the Access-Control-Allow-Origin: * header to all responses.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    
    // Adds headers: Access-Control-Allow-Origin: *
    app.use(cors())
    
    app.get('/products/:id', function (req, res, next) {
      res.json({msg: 'Hello'})
    })
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  6. Enable CORS for a single route

    master

    You can apply CORS middleware to specific routes instead of the entire application by passing cors() as a handler for that specific route.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    
    // Adds headers: Access-Control-Allow-Origin: *
    app.get('/products/:id', cors(), function (req, res, next) {
      res.json({msg: 'Hello'})
    })
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  7. Customize CORS settings dynamically per request

    master

    For APIs requiring different CORS configurations based on the request (e.g., different credentials for different paths), pass a function to cors(). This function is called for each request and must use the callback pattern: callback(error, corsOptions).

    Arguments:

    • req: The incoming request object.
    • callback: A function used to return the computed CORS options.
      • error: null if no error, or an error object.
      • corsOptions: An object specifying the CORS policy for the current request.
    var dynamicCorsOptions = function(req, callback) {
      var corsOptions;
      if (req.path.startsWith('/auth/connect/')) {
        // Access-Control-Allow-Origin: http://mydomain.com, Access-Control-Allow-Credentials: true, Vary: Origin
        corsOptions = {
          origin: 'http://mydomain.com',
          credentials: true
        };
      } else {
        // Access-Control-Allow-Origin: *
        corsOptions = { origin: '*' };
      }
      callback(null, corsOptions);
    };
    
    app.use(cors(dynamicCorsOptions));
    
    app.get('/auth/connect/twitter', function (req, res) {
      res.send('Hello');
    });
    
    app.get('/public', function (req, res) {
      res.send('Hello');
    });
    
    app.listen(80, function () {
      console.log('web server listening on port 80')
    })
  8. Configure CORS options

    master

    When initializing the cors middleware, you can provide an options object to customize CORS behavior. Supported keys include:

    • origin: Configures the Access-Control-Allow-Origin header. Can be a string, an array of strings, a Regular Expression, or a function that determines the origin dynamically.
    • methods: Configures the Access-Control-Allow-Methods header. Can be a string or an array of strings.
    • credentials: Set to true to enable Access-Control-Allow-Credentials.
    • allowedHeaders: Configures the Access-Control-Allow-Headers header. If not provided, it reflects the Access-Control-Request-Headers from the request.
    • headers: An alias for allowedHeaders.
    • exposedHeaders: Configures the Access-Control-Expose-Headers header. Can be a string or an array of strings.
    • maxAge: Configures the Access-Control-Max-Age header. Must be a number.
    • preflightContinue: A boolean. If true, the middleware calls next() after handling the OPTIONS preflight request. If false (default), it responds to the preflight request directly with the configured optionsSuccessStatus.
  9. Reference: CORS Configuration Options

    master

    The following options can be used to configure the cors middleware. The default configuration is:

    {
      "origin": "*",
      "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
      "preflightContinue": false,
      "optionsSuccessStatus": 204
    }
    * `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
      - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
      - `String` - set `origin` to a specific origin. For example, if you set it to
        - `"http://example.com"` only requests from "http://example.com" will be allowed.
        - `"*"` for all domains to be allowed. 
      - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
      - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
      - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
    * `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
    * `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
    * `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
    * `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
    * `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
    * `preflightContinue`: Pass the CORS preflight response to the next handler.
    * `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
  10. Use a dynamic origin function

    master

    To determine the allowed origin dynamically based on the request, you can pass a function to the origin option. This function receives the request origin and a callback. The callback should be called with (err, origin).

    If origin is provided as a function, the middleware will resolve it for every request.

  11. Use the cors middleware

    master

    The cors module exports a middleware function that can be used in Express or Connect applications to enable Cross-Origin Resource Sharing (CORS). You can initialize it by passing an options object, a function that returns options, or by calling it without arguments to use the default settings.

    Default settings:

    • origin: '*'
    • methods: 'GET,HEAD,PUT,PATCH,POST,DELETE'
    • preflightContinue: false
    • optionsSuccessStatus: 204