sync_sso ルートによる DiscourseConnect ユーザーデータの同期

シングルサインオン(SSO)を使用すると、別のサイトから Discourse のユーザー認証を処理できます。DiscourseConnect の実装方法の詳細については、Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) のトピックをご覧ください。

問題点

DiscourseConnect を使用すると、外部ウェブサイトから Discourse にログインした際に、Discourse ユーザーが作成または更新されます。しかし、ユーザーがサイトにログインすることなく、Discourse ユーザーを作成または更新する必要がある場合は対応できません。DiscourseConnect を使用しているサイトでは、これらのケースは、認証された POST リクエストを sync_sso ルートに送信することで処理する必要があります。

:information_source: Discourse API gem を使用している場合は、以下のコードの代わりに gem の sync_sso メソッドを使用できます。メソッドの使い方は、examples ディレクトリをご覧ください。

例として、親サイトでユーザーがグループに追加され、DiscourseConnect で最初にログインすることなく、Discourse 上の対応するグループに追加する必要があるケースを考えます。ウェブサイトとフォーラム双方のグループ名は「eurorack」です。ユーザーの external_id1、メールアドレスは bob@example.com です。以下のコードは PHP を使用していますが、基本的な考え方はどのプログラミング言語にも適用できます。

API 認証情報と SSS シークレットキーの設定

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

SSO パラメータの設定

利用可能なパラメータを確認するには、discourse_connect_base.rbACCESSORS セクションをご覧ください。既存のユーザーを更新するために 必須 のパラメータは external_id です。Discourse にまだ存在しないユーザーに対して sync_sso を呼び出す場合は、usernameemail パラメータを含める必要があります。Discourse は、新しいユーザーを作成するために usernameemail を使用します。

ユーザーをグループに追加するには add_groups パラメータを含め、グループから削除するには remove_groups パラメータを含めます。これらのパラメータの値は、グループ名をカンマで区切った文字列に設定する必要があります。グループ名の間にスペースは使用できません。

:information_source: require_activation パラメータがペイロードに含まれています。ユーザーのメールアドレスが親サイトで検証されていない場合は true に設定してください。PHP の場合、数値の 1 に変換されないよう、このパラメータは文字列の 'true' に設定する必要があります。ユーザーのメールアドレスが検証済みの場合は、このパラメータを含める必要はありません。

// SSO パラメータの配列を作成します。
$sso_params = array(
    'external_id' => 1,
    'email' => 'bob@example.com',
    'username' => 'bob',
    'add_groups' => 'eurorack',
    'require_activation' => 'true',
);

// SSO パラメータを SSO ペイロードに変換し、SSO 署名を生成します。
$sso_payload = base64_encode( http_build_query( $sso_params ) );
$sig = hash_hmac( 'sha256', $sso_payload, $discourse_connect_secret );

POST リクエストの送信

この例では curl を使用し、user_agent を ‘WordPress/4.9.4’ に、フォーラムの URL を 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 ) {
    // エラーを処理し、curl_close( $ch ) を呼び出して戻ります。
}

curl_close( $ch );

$discourse_user = json_decode( $result );

既存ユーザーの更新

sync_sso ルートへのリクエストは、ユーザーが DiscourseConnect でサイトにログインした場合と同じ方法で、既存ユーザーのプロパティを更新します。つまり、これらのリクエストに対しては、サイトの auth overrides および discourse connect overrides サイト設定の値が尊重されます。例えば、sync_sso へのリクエストで既存ユーザーのメールアドレスを更新するには、auth overrides email 設定を有効にする必要があります。関連する設定は以下の通りです:

  • auth overrides email
  • auth overrides username
  • auth overrides name
  • discourse connect overrides avatar
  • discourse connect overrides bio
  • discourse connect overrides groups
  • discourse connect overrides profile background
  • discourse connect overrides card background
  • discourse connect overrides location
  • discourse connect overrides website

さらなる参考資料

実際の動きを確認するには、sync_sso コードDiscourseConnectBaseparse メソッド、および DiscourseConnectlookup_or_create_user メソッドをご覧ください。

Node.js を使用している方のために、このガイドの JavaScript 版 も用意されています。

「いいね!」 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?
Sync_sso post suddenly resulting in 404 not found after succesfully adding a portion of the users
Changing avatar_url while sso_overrides_avatar is set?
"push" sso users to discourse?
Groups API - manually syncing group membership?
SSO_SYNC not working
PHP/API to check whether user exists (by email) and is in specific group
Pre-create user accounts for SSO users
User profile page by id?
DiscourseConnect Provider Questions
Logging in discourse using API - using discourse as API server only
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?
:cn: Synchronizing DiscourseConnect user data using sync_sso [Java] | 使用 sync_sso 同步 DiscourseConnect 用户数据 [Java]
Letting users choose whether to show Full Name
Auto-provisioning user accounts when SSO is enabled
Creating Discourse accounts during user import
Refresh sso groups
/admin/users/sync_sso 403 Forbidden
Triggering automatic authentication via SSO when linking to private topics?
"BAD CSRF" when executing PUT using API, curl, and PHP
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
Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)
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)
How to "intercept" first time SSO usages to let users confirm the SSO action and set a username?
API Create user external_ids parameter
First time login for a user using API KEY
How to use Discourse Connect (SSO) to update avatar, username, name?
How to set language for SSO users
What are your experiences with wp-discourse plugin and DiscourseConnect?

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