Synchronize SSO login state between Discourse and provider

I’m currently working on a website + Discourse SSO integration, the website is SSO provider. I’ve noticed a few tricky things and would like to document it down. Many of the information are from meta itself but are scattered in a few posts. I think it is better to have a single point of summary.

The official SSO document already provides detail of how to setup Discourse to integrate with external SSO provider. That one should be read very carefully. Here I’m focusing on how to made the login/logout state synchronized between Discourse and the reset part of the website(the SSO provider). This is quite important if you would like your visitors to have a good experience on the site. Without proper setup, the experience is bad in several ways, as described below in each section.

The term “website” in this post refers to the part of my site that is not backed by Discourse. It is the SSO provider for Discourse. If you are using WP or some other site builder, it is similar to implement.

Synchronize state from website to Discourse.

Login

When a user is logged in on the website, the URL that link to the forum site should be set to fourm.example.com/session/sso. Then when a user click this URL to visit forum, he will be logged in to Discourse automatically.

If your site allows anonymous browsing, make sure you detect the user login state and only append the /session/sso part for logged in user. For anonymouse user just direct them to forum.example.com/

Without this setup, when a user navigates to Discourse, he will need to click the Discourse login button to login.

Logout

When a user logout on the website, the website need to send a Discourse API request to this URL:

http(s)://forum.example.com/admin/users/{user_id}/log_out

The user_id here is the user ID in Discourse, it maybe different from the user ID in the website database.

How to get the user_id of Discourse

Quote from the official SSO document.

User profile data can be accessed using the /users/by-external/{EXTERNAL_ID}.json endpoint. This will return a JSON payload that contains the user information, including the user_id which can be used with the log_out endpoint.

So the website need to send the the user ID as above and get back the Discourse user ID, then logout the user.

Without this setup, when a user logs out from website, he is still in login state on Discourse. If he navigates back and forth between the site and Discourse, he will see unmatched login state, very confusing.

Synchronize state from Discourse to website

Login

No special handling required. When SSO is turned on in Discourse and a user click login button in Discourse, he will be redirected to website login page. Once logged in, he will be in logged in state on both website and Discourse.

Logout

The website needs to implement a logout URL such as https://example.com/logout

In Discourse site settings → users → logout redirect, fill in that URL. Then when user logs out from Discourse, he will be redirect to the website and log out there also.

Without this, when a user logs out from Discourse, he is still in login state on website.

12 Likes