What Is CORS?
CORS
stands for Cross-origin resource sharing.
Cross-origin
resource sharing is a mechanism that allows
restricted resources on a web page to be requested from another domain outside
the domain from which the first resource was served.
You only need to think about CORS when:
1. API
accessed by the browser
2. API
is hosted on a separate domain
How CORS Works?
CORS
allows the server to explicitly whitelist certain
origin and help to bypass the same-origin policy i.e.
var whitelist = ['https://code-sample.com', 'https://codefari.com']
If your server is configured for CORS, it will
return an extra header with "Access-Control-Allow-Origin"
on each response.
How to Enable CORS?
For enabling CORS on your server application, you
need two things.
1. First,
you need to determine the origins of whitelist
2. Second,
you have to add the CORS middleware to the server
Here, I am explaining to you the steps to
configure CORS on your Nodejs server.
Install the CORS npm package
-
> npm i cors
What
Is CORS NPM?
CORS is a node.js package for providing a
Connect/Express middleware that can be used to enable CORS with various
options.
Usage - Enable CORS Requests
After complete the installations, import these
files
var express = require('express')
var cors = require('cors')
var app = express()
The default configuration option is the
equivalent of:
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
Note - A dangerous practice for writing origin:*
in production.
To Configuring CORS for All Domains -
Example
1:-
var express = require('express')
var cors = require('cors')
var app = express()
app.get('/users/:id', cors(), function (req, res) {
res.json({msg: 'This is CORS-enabled for all domains.'})
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
Example
2:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
app.get('/users/:id', cors(corsOptions), function (req, res) {
res.json({msg: 'This is CORS-enabled for all domains.'})
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
To Configuring CORS for specific domains -
As
an Example,
var express = require('express')
var cors = require('cors')
var app = express()
var whitelist = ['https://code-sample.com', 'https://codefari.com']
var corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
}
else {
callback(new Error('Not allowed by CORS'))
}
}
}
app.get('/users/:id', cors(corsOptions), function (req, res) {
res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
Enabling CORS Pre-Flight:-
What
Is Pre-Flight request?
The CORS requests require an initial OPTIONS
request called the "pre-flight request".
Example
1:
var express = require('express')
var cors = require('cors')
var app = express()
app.options('/users/:id', cors()) // enable pre-flight request for DELETE request
app.del('/users/:id', cors(), function (req, res) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
You can also enable pre-flight across-the-board
like so:
app.options('*', cors()) // include before other routes
Example
2:
var express = require('express')
var cors = require('cors')
var app = express()
app.options('*', cors()) // enable pre-flight request for DELETE request
app.del('/users/:id', cors(), function (req, res) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
Configuration Options:-
1. origin:
Configures the Access-Control-Allow-Origin CORS header. Possible values:
a. Boolean
- set origin to true to reflect the request origin, as defined by
req.header('Origin'), or set it to false to disable CORS.
b. String
- set origin to a specific origin. Only requests from "http://domain.com"
will be allowed.
c. 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.
d. Array
- set origin to an array of valid origins. Each origin can be a String or a
RegExp.
e. Function
- set origin to a function implementing some custom logic. The function takes
the request origin as the first parameter and a callback as the second.
2. 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']).
3. 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.
4. 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.
5. credentials:
Configures the Access-Control-Allow-Credentials CORS header. Set to true to
pass the header, otherwise it is omitted.
6. maxAge:
Configures the Access-Control-Max-Age CORS header. Set to an integer to pass
the header, otherwise it is omitted.
7. preflightContinue:
Pass the CORS preflight response to the next handler.
8. optionsSuccessStatus:
Provides a status code to use for successful OPTIONS requests, since some
legacy browsers (IE11, various SmartTVs) choke on 204.
Is
enabling CORS safe?
The author of the Fetch/CORS spec goes into a bit
more detail in a related blog posting: It is completely safe to augment any
resource with Access-Control-Allow-Origin: * as long as the resource is not
part of an intranet (behind a firewall).
For resources where data is protected through IP
authentication or a firewall, using the CORS protocol is unsafe. Otherwise
using Access-Control-Allow-Origin: * is safe.
For details and download example on the CORS
configurations, read this article.