こんにちは、ユーザーが所属するグループを取得したいと考えています。get_discourse_user 関数からこの情報を取得できるはずですが、この関数はグループデータを返していないようです。こちらの投稿によると、取得できるはずですが?
WP Discourse 関数 get_discourse_user を呼び出していますか?もしそうであれば、ユーザーのグループは "groups" 配列で返されるはずです。
はい、私はこのように呼び出しています。
$discourseUser = \WPDiscourse\Utilities\Utilities::get_discourse_user( $current_user->ID, true );
var_dump($discourseUser);
そして、以下が返されます
object(stdClass)#2784 (25) { ["id"]=> int(7) ["username"]=> string(4) "chad" ["name"]=> string(13) "Chad Campbell" ["avatar_template"]=> string(59) "https://avatars.discourse.org/v4/letter/c/ecccb3/{size}.png" ["active"]=> bool(true) ["admin"]=> bool(false) ["moderator"]=> bool(false) ["last_seen_at"]=> string(24) "2019-10-25T15:59:45.439Z" ["last_emailed_at"]=> string(24) "2019-10-25T15:49:07.084Z" ["created_at"]=> string(24) "2019-10-24T21:22:40.526Z" ["last_seen_age"]=> float(2659.60627934) ["last_emailed_age"]=> float(3297.96116042) ["created_at_age"]=> float(69684.5193464) ["username_lower"]=> string(4) "chad" ["trust_level"]=> int(1) ["manual_locked_trust_level"]=> NULL ["flag_level"]=> int(0) ["title"]=> NULL ["suspended"]=> bool(false) ["time_read"]=> int(0) ["staged"]=> bool(false) ["days_visited"]=> int(2) ["posts_read_count"]=> int(0) ["topics_entered"]=> int(0) ["post_count"]=> int(0) }
関数呼び出しにおける true パラメータは、WordPress ユーザーIDに基づいてユーザーが見つからない場合、Discourse上でそのユーザーをメールアドレスによって検索するように関数を動作させます。これは、ユーザーがまだSSOでDiscourseにログインしていないことを意味します。メールアドレスに基づいてユーザーが見つかった場合、WordPress IDに基づいて見つかった場合よりも、Discourseから返される情報が少なくなります。
おそらく、この関数は戻り値をより明確にするために改善できるかもしれません。現時点では、レスポンスに groups 配列がない場合、ユーザーがメールアドレスによって見つかったと判断できます。
了解しました。説明ありがとうございます、サイモンさん!
こんにちは、サイモンさん、
SSO を通して Discourse にログインしたところ、email パラメータを false に設定すると、以下のエラーが表示されます。
object(WP_Error)#2718 (2) { ["errors"]=> array(1) { ["wpdc_response_error"]=> array(1) { [0]=> string(42) "The Discourse user could not be retrieved." } } ["error_data"]=> array(0) { } }
True に設定しても、グループが返ってきません。
SSO 設定により、Wordpress と Discourse の両方にログインでき(Wordpress 経由で両方からログアウトも可能)、設定は期待通りに機能しているはずですが、それでもグループが返ってこないため、少し混乱しています。
関数呼び出しの第 2 引数を false に設定するか、単にその引数を省略した場合(デフォルトは false)、その関数は WordPress の ID を基に Discourse からユーザーを取得しようとします。ユーザーが SSO で Discourse にログインしている場合、その関数はユーザーと所属グループを返すはずです。
これをデバッグするには、取得しようとしているユーザーの Discourse 管理ページに移動してください。ページの一番下にスクロールし、「Single Sign On」セクションがあるか確認してください。もしある場合、そのセクション内の「External ID」が、get_discourse_user を呼び出す際に使用している WordPress ユーザー ID と一致していることを確認してください。
ユーザーの Discourse 管理ページに「Single Sign On」セクションがない場合は、そのユーザーがまだ SSO で Discourse にログインしていないことを意味します。
はい、私がテストしたどのユーザーについても、そのセクションが存在していないようです。
ただ、どうやら私は SSO を通じてログインしているようですね。
以下がそのフローです(Wordpress や Discourse にはまだログインしていません)。
- Wordpress から「Discourse でログイン」リンクをクリック
- Discourse サイトに移動
- Discourse の認証情報でログイン
- Wordpress サイトに正常にリダイレクト
- これで両方のサイトにログインした状態に
正式な SSO として機能させるために、このプロセスで何が不足しているのでしょうか?
問題の原因がわかりました。WordPress 側で Discourse を SSO プロバイダーとして設定しようとしているようですが、その機能は実際には Discourse 側で WordPress を SSO プロバイダーとして使用する際に使うためのものです。機能名が不適切で、ユースケースが明確に伝わらないのが原因です。
Discourse を WordPress の SSO プロバイダーとして使用する場合は、/admin/users/$user_id.json に対して認証付きの API リクエストを送信する必要があります。ここで $user_id には、そのユーザーの Discourse ID を設定します。Discourse 経由で WordPress にログインしたユーザーの Discourse ユーザー ID は、以下の関数で取得できます。
get_user_meta( $wp_user_id, 'discourse_sso_user_id', true );
ああ、わかりました。API ドキュメントを詳しく見てみます。方向性を示してくれてありがとうございます!