Sync DiscourseConnect user data with the sync_sso route

Single Sign On can be used to handle Discourse user authentication from a separate site. The Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) topic has details about how to implement DiscourseConnect .

The Problem

With DiscourseConnect , Discourse users will be created or updated when they login to Discourse from your external website. What it doesn’t handle is when you need to create or update Discourse users without having them login to your site. For sites that are using DiscourseConnect , these cases should be handled by making an authenticated POST request to the sync_sso route.

:information_source: If you are using the Discourse API gem, you can use the gem’s sync_sso method instead of using the following code. See the examples directory for instructions on how to use the method.

As an example, we’ll take a case where a user is added to a group on the parent site, and they need to be added to a corresponding group on Discourse without having to first login with DiscourseConnect . The name of the group on both the website and the forum is ‘eurorack’. The external_id of the user is 1 and their email is bob@example.com. The following code is using PHP. The basic idea can be applied to any programming language.

Setup your API credentials and SSO secret key

$api_key = '4fe83002bb5fba8c9a61a65e5b4b0a3cf8233b0e4ccafc85ebd6607abab4651a';
$api_username = 'system';
$discourse_connect_secret = 'jdhb19*Xh3!nu(#k';

Setup the sso parameters

To see what parameters are available, have a look at the ACCESSORS section of discourse_connect_base.rb. The parameter that you must include to update an existing user is external_id. If you are calling sync_sso for a user who does not yet exist on Discourse, you must include the username and email parameters. Discourse will use the username and email to create a new user.

To add a user to a group, include the add_groups parameter. To remove a user from a group, include the remove_groups parameter. The value for either of these parameters needs to be set to a comma separated string of group names. Spaces are not allowed between the group names.

:information_source: The require_activation parameter is being included in the payload. This should be set to true if the user’s email hasn’t been validated on the parent site. With PHP the parameter needs to be set to the string ‘true’ to avoid it being converted to the number 1. If you have validated the user’s email address, you do not need to include this parameter.

// Create an array of SSO parameters.
$sso_params = array(
    'external_id' => 1,
    'email' => 'bob@example.com',
    'username' => 'bob',
    'add_groups' => 'eurorack',
    'require_activation' => 'true',
);

// Convert the SSO parameters into the SSO payload and generate the SSO signature.
$sso_payload = base64_encode( http_build_query( $sso_params ) );
$sig = hash_hmac( 'sha256', $sso_payload, $discourse_connect_secret );

Send the POST request

For this example I’ll use curl, set the user_agent to ‘WordPress/4.9.4’, and the forum URL to https://forum.example.com

$url = 'https://forum.example.com/admin/users/sync_sso';
$post_fields = array(
    'sso' => $sso_payload,
    'sig' => $sig,
);
$headers = array("Content-Type: multipart/form-data;","Api-Key: $api_key","Api-Username: $api_username",);

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $post_fields ) );
curl_setopt( $ch, CURLOPT_USERAGENT, 'WordPress/4.9.4' );

$result = curl_exec( $ch );

if ( curl_errno( $ch ) !== 0 ) {
    // Handle error, call curl_close( $ch ) and return.
}

curl_close( $ch );

$discourse_user = json_decode( $result );

Updating existing users

Requests made to the sync_sso route will update properties for existing users in the same way as would happen if the user logged into the site with DiscourseConnect . That means that the values of your site’s auth overrides site settings will be respected for these requests. For example, to update the email address for existing users with requests to sync_sso, the auth overrides email setting needs to be enabled. Here are the relevant settings:

  • auth overrides email
  • auth overrides username
  • auth overrides name

Further Reading

To see what is going on, have a look at the sync_sso code, the SingleSignOn parse method, and the DiscourseSingleSignOn lookup_or_create_user method.

There is also a JavaScript edition of this guide for those using Node.js.

「いいね!」 32
Sync DiscourseConnect user data with the sync_sso route [JavaScript]
/admin/users/sync_sso ... Route not found
SSO_SYNC not working
Using the API to create a user on an SSO only system
SSO integration & external profile sync help
Creating Discourse accounts via SSO without visiting the forum URL?
Discourse OpenID Connect (OIDC)
Sync_sso post suddenly resulting in 404 not found after succesfully adding a portion of the users
SSO_SYNC not working
"push" sso users to discourse?
Groups API - manually syncing group membership?
Changing avatar_url while sso_overrides_avatar is set?
PHP/API to check whether user exists (by email) and is in specific group
Logging in discourse using API - using discourse as API server only
Pre-create user accounts for SSO users
DiscourseConnect Provider Questions
User profile page by id?
First time login for a user using API KEY
"BAD CSRF" when executing PUT using API, curl, and PHP
Letting users choose whether to show Full Name
Dev Category sidebar
How to set language for SSO users
What are your experiences with wp-discourse plugin and DiscourseConnect?
I cannot add user to the discouse forum from a wordpress website when user added in a membership
Integration into custom auth system where emails are not unique?
/admin/users/sync_sso 403 Forbidden
:cn: Synchronizing DiscourseConnect user data using sync_sso [Java] | 使用 sync_sso 同步 DiscourseConnect 用户数据 [Java]
Refresh sso groups
Error 414 when posting/updating via API
Creating Discourse accounts during user import
How to use Discourse Connect (SSO) to update avatar, username, name?
Discourse OAuth2 Basic
Delete user avatar by API
Delete user avatar by API
Help me troubleshoot my Discourse SSO
Adding existing (and inviting new) users to a group
DiscourseConnect, SSO and E-Mail address confirmation
AUTOMATIC: Inviting every new SaaS signup into the Discourse Forum
Question necromancy: migrating from mattermost
Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)
Triggering automatic authentication via SSO when linking to private topics?
How to "intercept" first time SSO usages to let users confirm the SSO action and set a username?
API Create user external_ids parameter

メッセージが表示されています: {“failed”:“FAILED”,“message”:“ログインエラー”}