Add ability to set CORS allow-list in n8n webhooks

This is a continuation of a discussion that started in this post: How to call webhook triggered flow from frontend (avoid CORS errors)

When you send a request to n8n directly from a frontend inside a browser you get CORS issues unless you are requesting from the same domain.

This is not technically an issue with n8n, but instead this is a security “feature” that browsers have to protect users.

However, since we’re not able to set what we need in n8n to deal with this currently it would be nice to add this as a feature or guide for users that want to blend n8n with traditional coded frontends

The basic solution is to just use a proxy, but this can be impractical / not ideal for a couple of reasons:

  1. You happen to be using a statically generated frontend site from a framework like Nuxt.js / Next.js so you can’t proxy directly using a framework like Axios
  2. You don’t want to pay extra for a server just to proxy requests to avoid CORS
  3. You’re using some no-code frontend builder where it could be complicated to deal with a situation like this

Here’s some background on what we need to fix this issue

the server needs to send the Access-Control-Allow-Origin response header because requests trigger a CORS preflight, and so then the browser does an OPTIONS preflight.

**The solution is to configure the server to send the Access-Control-Allow-Originresponse header** and to handle theOPTIONS` request

Originally I have also had the impression that n8n should have handled CORS but at the end of the day, I guess that is architecturally safer to use a proxy instead.

I am using Lambda Functions on AWS to handle the POSTING of the data and the Authentication.
my requests to AWS API Gateway have 2 arguments {action,payload} with action I am passing the Webhook path (ashcode) and the payload is the data then I am posting. The AWS Lambda Environment Variables can handle the ENDPOINT URL and the base64 encoded combination of user:password used as basic auth for the webhook. AWS API Gateway has all the CORS configuration that you will need to setup in order to send the request to n8n and in the lambda function you can use fetch to proxy the request.

1 Like

Just another vote for this - seems a bit backwards that the self-hosted version can handle this but the cloud can’t.

I tried the same setup but with a different workflow vendor - Pipedream. There was no CORS issue there but replacing Pipedream with n8n prevented me to handle responses in the web application on production website (not locally hosted).

If anyone stumbles upon this, I’ve worked around the cors limitations by setting up a super simple docker nginx container that proxies traffic through to n8n with cors enabled:

# default.conf
# replace variables with actual host/port names

server {
listen 80;

location / {

    # add cors headers
    if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    # Custom headers and headers various browsers *should* be OK with but aren't
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    # Tell client that this pre-flight info is valid for 20 days
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain; charset=utf-8';
    add_header 'Content-Length' 0;
    return 204;
    if ($request_method = 'POST') {
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
    if ($request_method = 'GET') {
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;

    # Only requests matching the whitelist expectations will
    # get sent to the application server
    proxy_pass http://${NGINX_UPSTREAM_HOST}:${NGINX_UPSTREAM_PORT};
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache_bypass $http_upgrade;


New version [email protected] got released which includes the GitHub PR 7455.

1 Like