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.


When a user is logged in on the website, the URL that link to the forum site should be set to 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

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


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


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


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.


The website needs to implement a logout URL such as

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.


This is very important in this department and very relevant. At any point you can use the API to synchronise the account.

1 Like

Sam could you explain what exactly does “synchronize SSO record” mean here? Is it regarding sync the user session state or sync the user’s information such as email, avatar, bio etc.?

Yes, it basically simulates a user logging in to the site via SSO with all it entails, without the user actually logging into the site.

According to information I saw elsewhere in meta, only a SSO login action will refresh user information from the provider. Is that correct?

So the purpose of this sync_sso API is for user information refresh? As user still need to login in his browser to get the cookie, this API won’t help in saving a login button click, is it the case?

No, that is not correct, where did you see this?


No it will not :slight_smile:


From your post here

Since you said when SSO provider has a user email changed he need to do a logout then login, I’m under the impress that only a re-login action will refresh the user information from provider. (sync_sso API not counted).

It was not my intention to say that is the only way of doing it. Just the simplest way for most users.

Glad we clarified this here.


Ah got it. Thanks for the clarification.