Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)

I don’t have a local Discourse installation at the moment, so I’m not sure how much I can help.

The 404 response makes me wonder if Discourse Connect is actually enabled on your Discourse site:

It sounds like you are testing this with a local angular app and a production Discourse site. I’d expect that to still work, but possibly it’s causing an issue. You should definitely be able to get some kind of response other than a 404.

@simon thanks for you reply,
that had been confirmed several time by myself,

and I also have a production test site which was hosted on the parent domain of this discourse site. if you can take a look this [link redacted]
to test the production flow I updated the discourse Connect URL to “https://domainsite.com/login” please feel free to login with google provider and have a test. In the inspect console log you will see the error and the response I printed out, which is 404

since im just doing the POC if you don’t mind can leave me your email then i can set you to admin for investigating the configurations on my discourse site closely. Again really appreciate your time and help

the only part im not sure about is the sig and sso am i doing it correctly from the code ?
other then this part. the api-key i tried both, generating for everyone and only for system, the result are the same. if possible please provide me a working sample for postman or angular based code

I missed this when I first looked at the screenshot of your code:

mode: 'no-cors'

I’m not familiar with Angular apps, but it looks like you’re trying to make an authenticated API request to Discourse from the client. I’m not sure where it happens in the Discourse code, but my understanding is that Discourse blocks admin API requests that are made from the client. This is because there’s no way to make the request without exposing the API key on the client. Related to that, you should change your API key now.

1 Like

thanks for pointing this out,
feels like moving one step further.
I am also trying to send the request from postman as well.
if you think the block from the client side "mode: ‘no-cors’ "since discourse refused to accept the call with api keys from the front end then I think it should be OK to send it from postman is that correct ? but the result is the same


the sig and sso comes from the output of the ssoPayload and signature which I printed out during the process.

there must be something wrong, seems very close to target the root cause.

I even try to start a server then trigger the server to send the request with the apikey on server side which gives the same result, made me feels like I am missing some configurations on discourse site.

1 Like

Getting this to work from postman, or even just the command line, is a good idea. From the screenshot you posted, it looks like you’ve got the api-username and api-key in the body of the request. Those parameters need to be in the request header. The body of the request should contain the sig and sso key/value pairs. If it helps, here’s how the WP Discourse plugin handles it: wp-discourse/lib/plugin-utilities.php at main · discourse/wp-discourse · GitHub .

1 Like

wow! here we go,
now it is working !
1000 thanks @simon

the issue was just you mentioned:
sso and sig should be the only two key pairs in the body
api-key and api-username should be in headers

2 Likes

How will this behave if I turn this on on a site that doesn’t currently use external_id? Will it manage to login users based solely on their email?

More generally, since email and external_id are the 2 mandatory fields in the payload, could you clarify how they are used on the discourse side (when receiving the payload from the authenticating site) to figure which user account to login?

  • What if no external_id was associated with email during user creation, will it use email and then associate the external_id with this email for future logins?
  • What if there is a mismatch between email and external_id (each is associated with a different discourse account), will it use external_id or email to figure which user to login? Or throw an error?

Thank you!

I think your main question is about the external_id field. You need to set an external_id field in the DiscourseConnect payload. The value of the field should be some string that is associated with the user that will never change. I’m assuming that your application has a users table. The primary key for a user’s entry in that table would be good to use for the value of the external_id field.

If a user created an account on Discourse prior to your having added DiscourseConnect authentication from your website, the first time they log into Discourse through DiscourseConnect, Discourse will attempt to find the user based on the email address that’s in the DiscourseConnect payload. After finding the user, a record will be added to the Discourse database that contains the external_id from the DiscourseConnect payload. The next time the user logs in, they will be found by the external_id instead of by the email address. (Note that this doesn’t work if you set the require_activation parameter in the DiscourseConnect payload to true.)

Discourse has good fallbacks for most edge cases. There are issues related to users having multiple accounts and email address that can trigger errors. Some details about dealing with those cases are here: Debug and fixing common DiscourseConnect issues.

1 Like

Very helpful, thank you! Sounds like it all works like I expected :slight_smile:

1 Like