Cross-Origin Resource Sharing (CORS) is a security feature that allows web applications to interact securely with resources from different origins and denies unwanted communication. You might be reading this because your browser has blocked access to your Appwrite serverless function. This guide will help you "unblock" that access.
Understanding CORS
CORS controls how web applications interact with resources from different origins, preventing unauthorised requests from malicious websites. To allow cross-origin requests, servers must include specific headers in their responses that indicate which origins are permitted to access the resources.
How CORS works
When a browser makes a cross-origin request, it includes an Origin header with the request. The server can respond with various CORS headers to specify:
Which origins are allowed (Access-Control-Allow-Origin)
Which methods are allowed (Access-Control-Allow-Methods)
Which headers are allowed (Access-Control-Allow-Headers)
For certain types of requests, the browser sends a preflight (OPTIONS) request to check if the actual request is safe to send.
CORS in Appwrite serverless functions
In traditional Node.js and Express setups, CORS headers are often set using res.setHeader(). However, in Appwrite serverless functions, this approach won't work due to the way Appwrite handles responses. Instead, you should directly include CORS headers in the response returned by the function.
Steps to handle CORS
1. Create and deploy your serverless function
Start by creating and deploying your serverless function through the Appwrite console or CLI. This ensures your function is set up correctly within the Appwrite environment. Detailed steps can be found in the Appwrite Functions documentation.
2. Handle preflight (OPTIONS) requests
Preflight requests are sent by browsers to verify permissions before making actual requests. To handle these requests, check if the incoming request is an OPTIONS request and respond with the appropriate CORS headers:
if (req.method === 'OPTIONS') {
return res.send('', 200, {
'Access-Control-Allow-Origin': 'YOUR_DOMAIN_HERE',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
})
}
3. Include CORS headers in responses
For other requests (POST, GET, etc.), include the Access-Control-Allow-Origin header in the response to specify which origins are allowed to access the resource:
if (req.method === 'POST') {
try {
return res.json({ ok: true }, 200, {
'Access-Control-Allow-Origin': 'YOUR_DOMAIN_HERE',
})
} catch (error) {
return res.json({ error: 'Internal Server Error' }, 500, {
'Access-Control-Allow-Origin': '*',
})
}
}
Security considerations
Using the wildcard * in the Access-Control-Allow-Origin header allows any origin to access the resource. While this simplifies development, it can pose security risks if handled incorrectly. Malicious websites could exploit this vulnerability to make unauthorized requests to your serverless functions.
For example, here’s how you might configure CORS to allow access from any origin:
return res.json(completion, 200, {
'Access-Control-Allow-Origin': '*',
})
For better security, replace * with your specific domain name to restrict access to only trusted origins:
return res.json(completion, 200, {
'Access-Control-Allow-Origin': 'https://yourdomain.com',
})
This way, only requests originating from your domain will be allowed.
Conclusion
Handling CORS in Appwrite serverless functions ensures secure communication between your web applications and backend resources. By understanding how CORS works, you can prevent unauthorized requests and protect your serverless functions from potential security threats.