CORs Error on API Call to Auth0

Hi,

I’m getting an
AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK',...},
which is probably related to a CORS error on my request to my Auth0 API call.

I need to request my own API token from Auth0 in order to authenticate to my own database. However the CORS error below:

XMLHttpRequest at 'https://{tenant}.us.auth0.com/oauth/token' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

is what I get.

NOTE: I already added multiple URL links to my allow list including a lot of urls such as:
https://auth0.com/, https://auth0.com/, https://{tenant}/oauth/token, https://{tenant}.us.auth0.com/api/v2/ to the Allowlist for URL Fetching Domains and Allowlist panel Urls

My only thoughts on the points of error would be either on how my post request is defined, which I find hard to believe because I took it straight from the docs:

var axios = require("axios").default;

var options = {
  method: 'POST',
  url: 'https://{tenant}.com/oauth/token',
  headers: {'content-type': 'application/x-www-form-urlencoded'},
  data: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    audience: 'YOUR_API_IDENTIFIER'
  })
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});

Or something in my allowlist domains? … Maybe I’m missing a link to Auth0??

Can you please think of what I might be missing here?

This leaks your Auth0 client secret to anyone using the extension…

The remote server has set a header which disallows the access-control-allow-origin header being used in calls made to it.

This isn’t a “Twitch/Extension Configuration” problem.

It’s Auth0 blocking this request as it includes a disallowed header, in this case access-control-allow-origin is the conflicting header.

This is likely done to prevent you trying to generate a client_credentials token and leaking your client secret to the world

1 Like

Thats taken straight from their documentation. Thanks for the insight, I later figured that would be the problem too, however I wasn’t sure how to fix it. Thanks for the tip tho. Does the twitch extension add the access-control-allow-origin to all calls outgoing, and therefore being blocked by auth0?

However I fixed this by not going through Auth0.
I’m using passport now passport-http-bearer

As a followup,

What is the best way to hide the secrets in the extension? Using a file, then importing those secrets in?

You don’t

Secrets don’t go in the front end.

Why are you trying to Authenticate a user via oAuth in an extension front end?

Browsers do as part of CORS/browser security. Not Twitch Extensions.

For server to server, not browser to server.

Client Credentials is a token that represents a server for making server to server calls. Auth0 blocked it as you are doing it wrong.

The code sample is correct, but it’s not for using frontend code, hence the security block.

Why are you trying to Authenticate a user via oAuth in an extension front end?

Aparently I am doing it wrong :slight_smile:

So, I’m guessing the secrets go in the backend, but what about a twitch client-id, don’t you need to pass that to the api via the front-end?

ClientID’s are considered public, as they are the publical idnetifier for your project/product/whatever.

For an extension the URL for live is https://clientID.ext-twitch.tv/ETC (iirc)

And used as part of the URL to the extension in the product store.
And used in the URL to the entry point for oAuth.

You don’t need to oAuth in an extension for a viewer, as requestIDShare will let you ask a user to login to an extension to provide their userID.

Thank you for the amazing feedback Barry! As always.
Sounds good, if the ClientIDs considered public, I won’t worry too much about that.
As you said, I’ll move my secrets to the server side.

I haven’t heard of requestIDShare, it might help me when implementing my login/auth. The reason I needed to Authenticate a user is because I want to protect/secure my public api on my server. I’m creating a user/pass authentication system, to request an accesstoken. This accesstoken will be used to authenticate and hit the backend api, and get/set data based on the user who is authenticated. I have the system mostly set up to generate accesstokens for users, I just need to move my secrets to the backend.

This issue can now be closed. I’ll reach out if I need more help. I appreciate the conversation about security.

Thats the purpose of requestIDShare and the JWT that is passed to onAuthorised.

Any call you make from the frontend to your backend include the JWT as a header (or however you feel)

Then validate the JWT with your extension secret.
If the user has logged in (with requestIDShare) the JWT contains the userID of the user logged in.

And since the JWT is verified with your extension cleint secret. The mechnism you describe already exists built in to extensions.

This might help me save alot of time. I have to look into this more to get an understanding of the

Then validate the JWT with your extension secret.

If what you are saying is true, then the extension secret would live on the backend, so I can protect my calls from my frontend to the backend. I’ll have to look into that verification process.

At that point I can dish out my own access-tokens? Thats still something I would have to build (already built)

Correct!

There should be a suitable lib for your langauge of choice check out https://jwt.io/ for a list of libs and general information.

Theres no need imo, just use the JWT with all calls saves the overheard of any faff with “a second token” or having to pass that token down to the extension to use. Just use the JWT for all calls.

There should be a suitable lib for your langauge of choice check out https://jwt.io/ for a list of libs and general information.

Awesome I’ll check that out :slight_smile:

just use the JWT with all calls

I see… so post-verify, we should just allow the api call to go through after that. Duh! Haha. It makes sense now, I’ll probably have to do some thinking till I feel 100% on it but it makes sense.

Thanks!

Yup!

I’ll let you know how it goes!

I successfully passed the JWT token to the backend as a header, and decoded it with the secret.

However, I have a question, what’s stopping someone from getting the JWT token from the exchange between the frontend to the backend, and then using that to call my api?

Whats to stop them getting an access token and doing the same thing?

Only Twitch can generate JWT’s and those JWT’s are only valid for around an hour. Then onAuthorised it called and a new JWT issued.

1 Like