SSO 認証情報の有効期間 / 強制ログアウト

ユーザーが再ログインを求められるまでのセッション有効期間について、どのような目安を持てばよいでしょうか?

functions.php に独自の実装を追加し、WordPress の SSO プラグインと連携させています。ロジックは比較的シンプルだと思っていましたが、クレジットカードの支払いが拒否された(そのため、私のロジックがチェックするユーザータグが削除された)メンバーが、今日もフォーラムにアクセスできていることに気づきました。さらに確認したところ、彼女は数日前に最後にログインしており、おそらく現在もログインしたままの状態のようです。WordPress 上の最終ログイン日付も数日前となっています。

キャッシュされた認証情報がまだ機能していることは想定されるのでしょうか?もしそうであれば、トークンの有効期限を制御する方法や、Webhook への応答でログアウトを強制する方法はありますか?

よろしくお願いいたします。

これは Discourse の「maximum session age(最大セッション期間)」というサイト設定で制御されています。この設定は、ユーザーがサイトからログアウトされるまでの時間を時間単位で指定するものです。デフォルト値は 1440 時間(60 日)です。この値をより低い値に設定することも可能です。ただし、設定値が低すぎると、ユーザーにとってはバグのように感じられる可能性があります。

これは当然のことです。Discourse の管理ページにアクセスし、ページ右上近くにある「ログアウト」ボタンをクリックすることで、ユーザーを強制的にログアウトさせることができます。もう一つの選択肢として、WordPress サイトにコードを追加し、メンバーシップの有効期限が切れた際に Discourse から自動的にログアウトさせる方法もあります。

シモン、ありがとうございます。私のシナリオでは60日は長すぎると思います(これは有料会員であり、有効な会員かどうかを確認するという期待があるためです)。しかし、期間を短縮しすぎると手間がかかることにも同意します。

最後の提案(会員の終了時にDiscourseからログアウトする方法を見つけること)を調査します。手動でログアウトするオプションは見たことがありますが、これを完全に自動化したいと考えていますので、それが適切な道筋のようです。

改めてありがとうございます。

うーん…サイト設定の説明には(強調は私)とあります:

ユーザーは、最終訪問からn 時間ログアウト状態を維持します

私の理解が正しければ、SSO 資格情報を失った後でも定期的にサイトを訪問し続ければ、永久にログイン状態を維持できる可能性があります。例えば、設定が 72 時間の場合、毎日または 2 日に 1 回サイトを訪問し続けていれば、ログイン状態は維持され続けます。私の解釈は正しいでしょうか?

はい、私の経験ではその通りです。固定された期間後に強制的にログアウトさせる絶対的なタイムアウトはありません。

つまり、誰かが私のメンバーシップをキャンセルした場合、その人が私のフォーラムにアクセスできないように確実にするためには、強制的にログアウトさせる(手動で、または API 呼び出しを通じて)必要があるということでしょうか?

はい、それが推奨事項です

ありがとうございます。Facebook グループ(退会したメンバーを手動で削除する必要があった)から Discourse に移行したばかりですが、Discourse でも退会したメンバーがフォーラムにアクセスできないようにするために手動のプロセスが必要になるのは残念です。そこで質問があります。

非手動の仕組み(どんな創造的な方法でも構いません)で、有効なアカウントを持たなくなったユーザー(つまりログインできない状態)を Discourse から強制的にログアウトさせる方法はありますか?

SSO メカニズムがユーザーのログインをブロックする(有効なアカウントがないと認識する)のは論理的におかしいように思えますが、ユーザーが定期的(タイムアウト未満)にフォーラムにアクセスし続けている限り、私が手動でログアウトするまで、いつまでもフォーラムを利用できてしまいます。

最終的な選択肢として、キャンセル時に Discourse API を呼び出してログアウトさせるプラグインを作成するしかないかもしれません。

どんなアイデアでも歓迎します。お分かりの通り、この作業を手動で行うことは本当に避けたいのです :slight_smile:

ありがとうございました。

/admin/users/<discourse_user_id>/log_out に対して API リクエストを送信できます。WP Discourse プラグインは、WordPress からのログアウトを Discourse と同期させるためにこのルートを使用しています。おそらく、以下の関数のコードの大部分を流用できるでしょう: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub

シモン、ありがとうございます。確認いたします。

ただ、少し立ち止まって考えてみると、これは問題ではないでしょうか?その重要性については議論の余地があるかもしれませんが、アカウントが無効になった後もユーザーがフォーラムに無期限にアクセスし続けられるプラットフォームは、他に例を見たことがありません。

おそらく、Discourse ではなく WordPress が権威ある情報源であるという考えには納得できます。すると、論理を実装すべき最良の場所は SSO プラグインになるでしょう。

ここで全体の考え方を教えていただければ幸いです。一定期間経過後の強制ログアウトや、WordPress アカウントが「無効」になった場合の処理など、このシナリオは妥当だと思われますよね?

手作業を避けたいので、頭を悩ませているところです。できればコードを書くのも避けたいのですが :slight_smile:

はい、これは WordPress 側で処理する必要があります。WP Discourse プラグインが、ユーザーが WordPress で_削除_された際に Discourse からもログアウトさせる仕組みを導入するのは理にかなっていると思いますが、それであなたの問題が解決するかどうかはわかりません。私の推測では、あなたのサイト上でユーザーのメンバーシップが期限切れになっても、そのユーザーは WordPress サイトから削除されないのだと思います。メンバーシップの期限切れ時に Discourse からログアウトさせる処理を実現するには、おそらくあなたのサイト側にコードを追加し、メンバーシッププラグインが期限切れ時に発火するアクションにフックする必要があるでしょう。

@simon さん、改めてありがとうございます。ご指摘の点はごもっともですが、もしよろしければもう一度私の考えを述べさせてください :slight_smile:

ここには 2 つの要因が絡んでいるように思われます。1 つはアカウントの有効性(具体的には、そのユーザーがアクティブな会員かどうか)、もう 1 つは Discourse 側でのトークンの有効性です。

前者については、WordPress がこれを管理すべきだと完全に同意します。時間が許す限り、調査を進めます。

ただし、Discourse 側におけるアクティブ/有効なトークンに関する問題もあります。これが最優先事項ではないことは理解していますが、あるオプション(おそらくデフォルトではオフ)に「強制ログイン」の期間を設定するロジックには理があるように思えます。つまり、ユーザーが直近にログインしていなくても、x 日後にはログイントークンが期限切れになるという仕組みです。

繰り返しになりますが、これはあくまでブレインストーミングの段階ですが、ユーザーが有効なアカウントを持っているかどうかに関わらず、ログアウトを強制するオプションに一定の価値があると考えています。

WordPress を使用していないため、ウェブリンク経由でこれを行おうとしています。以下のような方法で可能でしょうか?

https://community.mysite.com/admin/users/100004/log_out

しかし、404 エラーが表示され、ユーザーはログアウトされません。

URL が機能すれば、PHP で curl または file_get_contents コマンドを使用して強制的にログアウトさせたいと考えています。

認証されたPOSTリクエストをルートに対して送信する必要があります。リンクをクリックしたときにユーザーをログアウトさせるように設定することもできますが、その場合はサーバー側でリクエストを処理する必要があります。

ありがとうございます!認証済みですね?これについて調べてみると、PHP からの認証付き投稿では、ヘッダーに以下のような内容を送信しているようです:

'Authorization: OAuth '.$accesstoken;

他にもいくつかの手がかりが見つかりましたので、引き続き調査します。

もし動作する PHP のコードスニペットをお持ちの方がいたら助かります!https://docs.discourse.org/ の認証セクションにある例は、私には構文エラーとして返されてしまいました……あ、待ってください、あれは Unix コマンドでした!

PHP に関する役立つ手がかりがあれば、ぜひお知らせください!

前の投稿からのリンクで十分だと思います:wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub サイトからリクエストを送信していない場合は、wp_remote_post リクエストを別の方法で行う方法を考える必要があります。

単純な PHP コマンドを使えば、もうすぐ解決できそうです。コードは以下の通りです。ユーザー名の選択は、この投稿 から得たものです。

このようなレスポンスが返ってきました。何か意味がわかりますか?SSL プロトコルのバージョンの問題のようです。

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

コードはこちらです:

    $url = "https://community.mysite.com/admin/users/100004/log_out";
    $headers = array( 'Api-Key' => 'd412mylongadminkeyaadcd',
                    'Api-Username' => 'system',
                    );

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);

[編集:これらの行を追加しましたが、変化はありません:]
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
[/編集]

	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        echo curl_error($ch);
    }
    curl_close($ch);

WordPress を使用している場合、wp_remote_post 関数を使ってリクエストを送信してみてください。そうすれば、curl オプションを扱う必要がなくなります。

ありがとうございます。ただ、私は WordPress を使用していません。過去 10 年間にわたって自分で構築したメンバーシップ管理システムで、PHP を使ってこれを実現しようとしています。

PHPライブラリがDiscourseのHTTPS証明書を受け入れられなかったようです。そのエラーについてはGoogleで検索してみてください。