CORS in CouchDB is actually a security feature designed to prevent malicious websites from making requests to your CouchDB instance on behalf of a logged-in user.
Let’s see CouchDB’s CORS in action. Imagine you have a simple HTML page served from http://localhost:8000 that needs to access your CouchDB running on http://localhost:5984.
<!DOCTYPE html>
<html>
<head>
<title>CORS Test</title>
</head>
<body>
<h1>CouchDB CORS Test</h1>
<button onclick="fetchData()">Fetch Data</button>
<pre id="output"></pre>
<script>
async function fetchData() {
const url = 'http://localhost:5984/_all_dbs';
try {
const response = await fetch(url);
const data = await response.json();
document.getElementById('output').textContent = JSON.stringify(data, null, 2);
} catch (error) {
document.getElementById('output').textContent = `Error: ${error.message}`;
console.error("Fetch error:", error);
}
}
</script>
</body>
</html>
If you open http://localhost:8000 in your browser and click "Fetch Data" without proper CORS configuration on CouchDB, you’ll see an error in the browser’s developer console, something like:
Access to fetch at 'http://localhost:5984/_all_dbs' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is CouchDB protecting itself. It doesn’t want http://localhost:8000 to freely access its data unless explicitly allowed.
To fix this, we need to configure CouchDB. CouchDB’s CORS settings are managed via its configuration file, local.ini. You’ll find this file in your CouchDB installation directory, often in a etc/couchdb subdirectory.
Here’s how you configure it. Open local.ini and add or modify the [cors] section.
[cors]
cors_enable = true
origins = http://localhost:8000, https://your-frontend-domain.com
methods = GET, PUT, POST, DELETE, HEAD
headers = Accept, Authorization, Content-Type, Origin
credentials = true
max_age = 3600
Let’s break down these options:
-
cors_enable = true: This is the master switch. Set it totrueto enable CORS handling. If this isfalseor missing, CORS is effectively disabled, and CouchDB will not send the necessary CORS headers. -
origins: This is the most critical setting. It’s a comma-separated list of origins (scheme, hostname, and port) that are allowed to make requests to your CouchDB instance. In our example,http://localhost:8000is added here. For production, you’d replace this with your actual frontend domain(s), likehttps://your-frontend-domain.com. If you want to allow any origin (which is generally not recommended for security reasons unless you have other strong access controls), you can use*. However, using*withcredentials = trueis not allowed by browsers. -
methods: This specifies the HTTP methods that are allowed from the permitted origins.GET, PUT, POST, DELETE, HEADcovers most common operations for interacting with CouchDB documents and views. -
headers: This lists the HTTP request headers that are allowed.Accept, Authorization, Content-Type, Originare common headers needed for API interactions, especially if you’re sending JSON data or using authentication tokens. -
credentials = true: If your frontend application needs to send cookies or authorization headers with its requests to CouchDB (e.g., usingfetchwith{credentials: 'include'}or passing anAuthorizationheader), you must set this totrue. This tells CouchDB to include theAccess-Control-Allow-Credentials: trueheader, which is required for browsers to allow credentials to be sent. -
max_age: This is the maximum time (in seconds) that a browser can cache the results of a preflightOPTIONSrequest. A value of3600(1 hour) is common. This reduces the number ofOPTIONSrequests the browser makes.
After modifying local.ini, you need to restart CouchDB for the changes to take effect. The exact command depends on your operating system and how CouchDB was installed. For example, on a system using systemd:
sudo systemctl restart couchdb
Once CouchDB is restarted, refreshing your HTML page and clicking "Fetch Data" should now succeed, and you’ll see the list of your CouchDB databases.
The one thing most people don’t realize is that credentials = true has a cascading effect. When this is set, CouchDB will only respond to origins explicitly listed in the origins setting. It will not fall back to * even if * is present in origins. This is a security measure to prevent accidentally exposing credentials to unintended origins.
The next problem you’ll likely encounter is managing authentication and authorization for browser-based clients, as CORS only handles the network-level access control.