Webhook Authentication with fetch()

Describe the issue/error/question

I have been trying to Basic authenticate a POST webhook in workflow test-mode from a self-hosted Seatable using fetch() in Seatable’s Javascript scripts.
Wasn’t able to find an example on either the documentation or the forum, though I’m probably not the first doing this.

I thought this should have been enough:

const username = "n8n-basic-auth-USER";
const password = "n8n-basic-auth-PASSWORD";
let data = {
  row_id: base.context.currentRow['_id']
};

await fetch(url, {
  method: 'POST',
  credentials: 'include',
  mode: "no-cors",
  headers: {
    'Content-Type': 'application/json', 
    'Authorization': "Basic " + btoa(`${username}:${password}`)
  },
  body: JSON.stringify(data)
}).then(res => {
  console.log('Request complete! response:', res);
});

I get a 403 Error and been looking at specifications for a while now, trying different things.
It’s probably an easy fix, one suspicion I have is that the request from Seatable Javascript script originates from seatable.mydomain.com and goes to n8n.mydomain.com and gets rejected?

In n8n I have set my Basic Auth credentials with User = ‘n8n-basic-auth-USER’ and Password = ‘n8n-basic-auth-PASSWORD’ (in reality a 44-character string with uppercase, lowercase, digits).

Without authentication it works fine, so I guess I’m fucking up somewhere essential and can’t see it right now : D Any pointers would be much appreciated!

Information on your n8n setup

  • n8n version: 0.193.5
  • Database you’re using (default: SQLite): Postgres
  • Running n8n with the execution process [own(default), main]: main
  • Running n8n via [Docker, npm, n8n.cloud, desktop app]: Docker
    Using traefik as a reverse proxy.
    Not using user management, but Basic Auth for logging into my n8n.

Hey @leprodude,

Is the Basic auth on the webhook node or just on the n8n instance? From what I remember when using Basic auth for the n8n instance the webhook urls don’t get configured to use the same auth and instead that is handled per webhook so it could just be that the webhook is not using any auth method and that is why it works with no credentials.

I use Basic Auth for logging into my n8n. Then I enable Basic Auth for the specific webhook and fail to authenticate via fetch() with those webhook Basic Auth credentials. If I disable the webhook Basic Auth it works fine. I hope it is even clearer now!

Hey @leprodude,

That is indeed clearer it was worth checking, The 403 tends to be a forbidden error which sounds like the credentials could be wrong.

As a quick test though have you tried using CURL or Postman / Insomnia to send the same request to see if that works?

With Curl it would be something like…

curl -X POST -d 'name=test' -u n8n-basic-auth-USER:n8n-basic-auth-PASSWORD https://n8n.your-domain.tld/webhook-test/SOME_ID```

With curl it works with authentication. Credentials I’ve always copy / pasted so I shouldn’t have a typo as reason…

If it works with curl the only thing I can think of is something isn’t being sent correctly from Fetch(), As a quick test I have just sent your same request off from the browser console and I got the auth prompt.

I have removed the “credentials” and “mode” options and that has worked so it looks like one of those options is causing the issue although I would have to check the docs for fetch to see what each one actually does.

Hopefully this helps though.

1 Like

Thank you! I’ll try and see if I can get it to work in the end…

If it helps the below is what worked for me.

const username = "n8n-basic-auth-USER";
const password = "n8n-basic-auth-PASSWORD";
let data = {
  row_id: base.context.currentRow['_id']
};

await fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json', 
    'Authorization': "Basic " + btoa(`${username}:${password}`)
  },
  body: JSON.stringify(data)
}).then(res => {
  console.log('Request complete! response:', res);
});
1 Like

I would expect that to work for me as well, but I keep getting this:

In Firefox I get:

When I add mode: "no-cors" and headers:{'Access-Control-Allow-Headers': 'Authorization, Content-Type'} I get a 401 and when I add credentials: "include" I get a 403.

Where / How did it work for you?
I guess the problem is that it’s being triggered from my browser…

I ran my request in my browser while on the same site, Looking at yours you will need to resolve the CORS issue first so that you can use the authorization header.

This may be something that has to happen on the Traefik side.

1 Like