Cross-Origin Resource Sharing (CORS) is a security feature implemented in web browsers to prevent web pages from making requests to a different origin (domain, protocol, or port) than the one the web page was loaded from. This tutorial will cover the basics of CORS, how it works, and how to implement it in your web application.
What is CORS?
CORS is a mechanism that allows a web page to make requests to a different origin than the one it was loaded from. It does this by adding additional headers to the request and response, which allow the browser to determine whether the request should be allowed or not.
How CORS Works
When a web page makes a request to a different origin, the browser adds an Origin
header to the request, which specifies the origin of the web page. The server then responds with an Access-Control-Allow-Origin
header, which specifies the origins that are allowed to make requests to the server.
If the Access-Control-Allow-Origin
header matches the Origin
header, the browser allows the request to proceed. If not, the browser blocks the request and returns an error message.
Implementing CORS
To implement CORS in your web application, you need to configure your server to include the necessary headers in its responses. The most common headers used in CORS are:
Access-Control-Allow-Origin
: specifies the origins that are allowed to make requests to the server.Access-Control-Allow-Methods
: specifies the methods (e.g., GET, POST, PUT, DELETE) that are allowed to be used in requests to the server.Access-Control-Allow-Headers
: specifies the headers that are allowed to be included in requests to the server.
Here is an example of how you might configure a Node.js server using the Express framework to include these headers:
const express = require('express');
const cors = require('cors');
const app = express();
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
optionSuccessStatus: 200,
};
app.use(cors(corsOptions));
In this example, the origin
option specifies that only requests from http://localhost:3000
are allowed. The credentials
option specifies that credentials (e.g., cookies) should be included in requests.
Handling Preflight Requests
Some requests, such as those with custom headers or non-standard methods, require a preflight request to be made before the actual request can be sent. A preflight request is an OPTIONS request that includes the Access-Control-Request-Method
and Access-Control-Request-Headers
headers.
To handle preflight requests, you need to configure your server to respond to OPTIONS requests with the necessary headers. Here is an example of how you might do this:
app.options('*', (req, res) => {
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.send();
});
In this example, the server responds to OPTIONS requests with the Access-Control-Allow-Methods
and Access-Control-Allow-Headers
headers.
Client-Side Implementation
On the client-side, you don’t need to do anything special to use CORS. The browser will automatically include the necessary headers in requests and handle preflight requests for you. However, if you’re using a library or framework that makes requests on your behalf, you may need to configure it to include the necessary headers.
For example, if you’re using the Fetch API, you can include the mode
option set to 'cors'
to enable CORS:
fetch('https://example.com/api/data', {
mode: 'cors',
credentials: 'include',
});
In this example, the mode
option specifies that CORS should be used, and the credentials
option specifies that credentials (e.g., cookies) should be included in the request.
Conclusion
CORS is an important security feature that helps prevent malicious scripts from making unauthorized requests on behalf of users. By understanding how CORS works and implementing it correctly in your web application, you can ensure that your users are protected from these types of attacks.