I was able to use this to create an account linking system for my Minecraft server! Thought I’d share what it looks like! This was my first time working with Discourse SSO, so I might’ve overcomplicated everything. However, it works, which is the main thing.
Hi i did all these correctly. but when the user is not logged in discourse it will show user login popup. when I fill username and password, it does not redirect me back to return_url. can you please help me?
I assume the
nonce is there to prevent replay attacks. I read online that replay attacks aren’t possible with HTTPS, which is what I’m using. So do I still need to do the nonce? I ask because I’m not sure where to store it. Does it make sense to store it as a secure, plain text cookie in the user’s browser? and then read it from the browser along with the return payload?
This library, which is linked from the original post GitHub - ArmedGuy/discourse_sso_node: npm package for Discourse SSO login features. doesn’t use the nonce when validating the user.
Yes, you still need to validate the nonce because it prevents reusing payloads that Discourse sends when it redirects users back to your site.
For example, let’s your site has some content behind a paywall that only members of the
subscribers group on Discourse can access and you use the
groups field in the payload that Discourse sends to your site to display the paid content only to members of the
subscribers group. If you don’t validate the nonce, a user who is no longer in the
subscribers could use an old payload from when they were a member to login to your site and see the paid content.
It’s best to store the nonce in a database with a short expiration date and delete the nonce from the database as soon as it’s used. However, if you can’t use a database, then you can use a cookie to store the nonce, but you need to do some additional steps to prevent payload reuse:
- attach an expiration date to the nonce when you generate it, for example 10 minutes from the current time
- sign the whole cookie (nonce + expiration date) to prevent users from modifying the nonce and/or the expiration date
- verify the signature of the cookie and ensure the nonce isn’t expired
That should give you a good enough protection against payload reuse. Keep in mind that technically it remains possible to reuse a payload, but it’ll be limited to a 10 minutes window instead of forever.
A simpler solution that doesn’t need a cookie is to include the expiration date in a custom field in the payload that you generate. Then when Discourse redirects users back to your site with a payload, your custom fields will be included and you can retrieve the expiration date and you verify it’s not expired. To include a custom field in the payload, you need to include a field prefixed with
custom., so your payload would look like this:
You could also store the nonce in the session, that will prevent the user from tampering with it as well.
Just circling back to this thread years later
Can someone tell me (@pfaffman or @tobiaseigen or @iamntz) what the Discourse SSO provider returns? I know I can “try it and see” but it would be nice to have it documented. The github PHP sample code doesn’t trally have any other fields even mentioned.
Ideally, it would send the same fields as when Discourse uses the external script for SSO, such as external id, email, username, name, avatar photo etc. So we can import this and create a user on our side!
Does it also tell Wordpress the email?
How about groups, badges etc? Can we find this information by making REST calls?
Finally, what about the user’s private messages and other stuff? I guess if Discord was an oAuth provider and allowed our apps to consume this sruff, that would be awesome.
When trying to enable Discourse Connect I get this error:
enable_discourse_connect: You cannot enable DiscourseConnect and invite only at the same time.
I see you have asked the same question here: Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) - #537 by Roie_Natan. If you are trying to configure the
enable discourse connect setting and not the
enable discourse connect provider setting, the other topic is the correct place to ask your question.
enable discourse connect provider setting is for when you want to use your Discourse site as the identity provider for another site. The
enable discourse connect setting is for when you want to log users into Discourse via an external site.
I’ve implemented the procedure in Python for a Flask application I am building. Here is some boilerplate code for anyone who needs it. The steps laid out in this topic were pretty simple to follow but I’m not a security specialist so if I overlooked anything please let me know!
We are trying to implement using Discourse as an SSO provider and what we do not understand is how does Discourse know which user needs to be verified? So the directions say: “Create a new payload with nonce and return url”. But when you post this via a fetch to Discourse, how does Discourse know what user to check to see if they are logged in? Sorry, if this sounds like a stupid question, but I just cant understand how this is working and I’ve worked with alot of Auth systems over the years, so somewhat familiar. Is the user email we are trying to check the login status for, need to be included in the payload sent to Discourse? If so, what is the exact structure of the payload that needs to be sent to Discourse. If not, again what is Discourse is checking exactly? My assumption is that we ask the user for their email on our end, and then send the payload with email to Discourse to see if that particular user is logged in, but this is not wha the directions say, so I’m totally confused. thanks for any help.
Never mind. We figured this out. We thought the SSO URL need to be sent as a POST request to the Discourse instance and then receive a response. Now we see this is a redirect to Discourse, and then Discourse then redirects back to our site. So it’s clear now what to do. Sorry for previous post.