API CORS Headers Incorrect

Hi,

I am having an issue with embedding discourse in our intranet site.

The API documentation states the discourse request requires the headers “API-Key” and “Api-Username” to authenticate and gain access to the feed. However the Pre-flight check says that “User-API-Key”, “User-Api-Client-Id” are the allowed values.

When called not through a browser this work as expected. But when calling through the browser the server is claiming it requires “User-API-Key”, “User-Api-Client-Id”.

I checked basic connection worked with PostMan this behaves as per the discourse docs

If we pass the Headers from the Docs the browser blocks the request due to Pre-flight check and gets a Access-Control-Allow-Headers CORS error.

If we pass the headers the server will accept we get a “not authorised error” because the application expects differently named values.

I have tried adding headers to the docker config but it doesn’t seem to apply. The CORS enabled and origin of ‘*’ is in the config.

Can anyone advise?

Thanks,
Jessica

1 Like

Just wondering if there was any more info on the above? Is this a bug or something I’m doing wrong?

Thanks,
Jessica

1 Like

We have two different API authentication systems, which can be confusing.

These are for the ‘admin API’, which is described on docs.discourse.org. This is not designed to be used from javascript clients.

These are from the “User API” specification, which can be used from a javascript client (and therefore supports CORS). There are more details about this here: User API keys specification

5 Likes

@david I’m using SSO and want to log the user out of Discourse when they log out of the app. I’m currently using the ‘admin API’ to fetch the the user ID via /users/by-external/${id}.json but I’m getting CORS errors - I don’t want to enable the ‘user API’ for every user just for this logout process - what do you suggest?

What is making the admin api request? JavaScript in your client application?

You shouldn’t include an admin API in a JavaScript client, it means everyone using the client could gain admin access to your site.

3 Likes

Yeah, it’s javascript in my app. I understand. So what’s the alternative? Can I add a ‘user API’ for one user and use that to make the call for all users?

If you use the user api, you should do it per-user. You should not share keys.

But the most common thing here would be to handle it on the server-side of your app. Your server can send a request using admin API keys without CORS issues, and with fewer security concerns (as long as it’s implemented safely)

2 Likes

Thanks @david. That’s helpful, I’ll sort it that way. Thanks again.

2 Likes

Hi @david, I’ve tried to implement a backend solution but when I call https://example.com/users/by-external/{EXTERNAL_USER_ID}.json?api_key={DISCOURSE_API_KEY}&api_username=system, the response i get is the html for the sign in page (I’m guessing it’s redirecting there). I have login required enabled and when I disable it, I get the correct JSON response. I want to keep that setting enabled - any ideas what’s going on?

You need to use headers for the API key and username. Check http://docs.discourse.org/ for details.

5 Likes

That sorted it, thank you again. :+1:

3 Likes