WordPressプラグインの無効な状態エラーのトラブルシューティング

WordPressプラグインのバージョン3.6.0に状態検証が追加されました。このバージョンはwp-auth0 GitHubリポジトリにあります。このセキュリティ対策では、CSRF攻撃を軽減できるように、同じユーザーによって開始された要求に対する応答であることを確認します。詳細については、OAuth 2.0の状態パラメーターを使って攻撃を防ぎ、ユーザーをリダイレクトするをお読みください。

状態検証の仕組み

プラグインは以下のようにして状態検証を行います。

  1. Lockのログインフォームが表示されているときに(wp-login.phpで、またはショートコードまたはウィジェットを使用したその他のページで)、JavaScriptを使用してブラウザーにauth0_state Cookieを設定します。

  2. Lockが埋め込まれたログインフォームにこの値を渡して、認証要求で送信できるようにします。

  3. Auth0のログインが成功した場合、変更されていないその値をAuth0からstate URLパラメーターで受け取ります。

  4. 受け取ったその値が、送信され、auth0_state Cookieに保存された値と一致しているか検証します。一致した場合には、ログイン処理が続行されます。一致しなかった場合には、ログイン処理を停止して、「無効な状態」エラーのメッセージを表示します。

  5. 結果にかかわらず、Cookieを削除します。

  6. 一致した場合には、リダイレクトやその他のログイン操作の実行に、base64でデコードされたオブジェクトの値を使用します。

この処理は、ログインしているユーザーとサイト管理者には完全に不透明でなくてはなりません。Auth0サーバーは状態値の検証や要求はしません。受け取った値をそのまま変えずに、コールバックURLへ返します。「無効な状態」メッセージが表示されたら、上記1~4のいずれかの手順が実行されません。

無効な状態エラーによくある原因

以下では、無効な状態エラーの一般的な原因と問題を解決する手順について説明します。

キャッシュされているコールバックURL

無効な状態エラーの最もよくある原因は、コールバックURLがサーバーでキャッシュされている場合です。

[Auth0 Dashboard] > [Applications(アプリケーション)] > [Applications(アプリケーション)] > [Settings(設定)][Allowed Callback URLs(許可されているコールバックURL)]フィールドにリストされているすべてのURLについて、サーバーのキャッシュを除外し、再度テストしてください。さらに、Auth0 URL パラメーターがある場合は、サイトURL(通常のインストールでは/index.php)のキャッシュも除外してください。

サーバーの時間が間違って設定されていないかを確認します。BeforeValidExceptionエラーは、現在の時間よりも前に生成されたトークンだと分かった際に発生するもので、サーバーの時間設定が間違っている場合に起こります。サーバーの時間設定は、echo current_time( 'c' )を使って確認できます。サーバーの時間を変更できない場合には、一時的な回避策として、時間のオフセットを追加するようプラグインを変更することもできますが、運用までに修正してください。

それでも問題が解決されない場合には、以下のトラブルシューティングを試してみてください。

キャッシュされたCookieとURLパラメーター

WP-Engineなど、管理対象ホストの場合には、担当のサポートチームに追加のサポートを依頼してください。コールバックURLで必要なCookieを使用できない問題や、ログイン後のユーザーに表示される最終ページで認証を確認できない問題が報告されています。具体的に、以下をキャッシュ対象から除外してもらってください。

  • Cookie:auth0_state

  • Cookie:auth0_nonce

  • Arg/URLパラメーター:auth0

  • Arg/URLパラメーター:code

  • Arg/URLパラメーター:state

  • Arg/URLパラメーター:id_token

エラーメッセージ後のページ更新

他のエラーメッセージ(メール検証など)が表示された後でページを更新すると、すでに使用済みの値を検証し直そうとするため、無効な状態メッセージが表示されます。これは正常な動作です。

Cookie名に関する要件

Pantheonなど、ホストによっては、特定のCookie名の使用を要求するところもあります。テーマまたはカスタムプラグインでauth0_state_cookie_nameフィルターを使用して、Cookie名を変更できます。auth0_state_cookie_nameフィルターの詳細については、Auth0 Wordpressプラグインのログイン時間を延長するをお読みください。その他の情報については、関連するGitHubの問題を参照しその修正方法を確認してください。

ユニバーサルログインページとリンクの作成

サイトがユニバーサルログインを使用していて、テーマやプラグインで独自にリンクを作成している場合には以下を行います。

  • auth0_stateという名前のCookieを、ランダムに生成された値で設定します。

  • その値をstate URLパラメーターで送信します。

または、[Settings(設定)] > [Features(機能)]タブ > [Universal Login Page(ユニバーサルログインページ)]に移動し、ログイン要求をwp-login.phpページにリダイレクトすれば、そのCookieとURLパラメーターが自動的に設定されます。カスタムで作成した/authorize URLを引き続き使用する場合は、GitHubリポジトリでこの処理を実行するコードを確認できます。

コールバックURを直接開く

コールバックURL(通常はyourdomain.com/index.php?auth0=1)を直接、または認可コードの交換後の二度目に開く場合には、無効な状態エラーが表示されることがあります。これは、状態がすでに確認され、削除されていることを示しています。

無効な状態エラーのトラブルシューティング

以下にある一部の手順には、ログイン処理の中断(注記あり)が必要になります。

  1. WordPressとAuth0からログアウトする際に、テストするログインページを開きます。

  2. auth0_state Cookieが設定されているか確認します(Chromeでは[View(表示)] > [Developer(デベロッパー)] > [JavaScript Console(JavaScriptコンソール)] > [Application(アプリケーション)]タブ > 左の[Storage(ストレージ)] > [Cookies] > テスト中のドメインに移動し、値が空ではないauth0_state Cookieを探します)。

    • この値が設定されていない場合には、JavaScript Consoleでエラーを探して、使用しているブラウザーがCookieを許可できることを確認します(Cookieを使用しないとログインは動作しません)。これは/assets/js/lock-init.jsで設定されています。このコードはGitHubで表示できます。

    • 値が設定されている場合には、その値をコピーして、ページのソースコードを表示します(Chromeでは[View(表示)] > [Developer(デベロッパー)] > [View Source(ソースを表示)])。この値を検索します。wpAuth0LockGlobal.settings.auth.params.stateパラメーターに関連付けられた値として表示されます(サンプルのJSONを表示)。この値を書き止めます(以下の手順で必要になります)。

  3. 値が表示され、Lockフォームが正常に読み込まれている場合には、上記の手順1と2が正常に機能していることになります。

  4. テストインストールを行えるように、ログインする前にwp-config.php一番上にこのコードスニペットを追加します警告:テストしているWordPressサイトのログインが切断されるため、必ず運用環境以外のインストールで使用してください。

  5. 通常通りにログインします。

  6. サイトのコールバックURLにリダイレクトで戻されると、処理が停止します。上記の手順4のGitHub Gistリンクにあるような出力が見えるはずです。Array()のようなものがあり、追加の値がない場合には、以下のいずれかが該当する可能性があります。

    • WordPressコールバックURLがキャッシュされている。ページのキャッシュはさまざまな方法で行われるため、ここでは手順を明確に提供できません。インストールされているキャッシュプラグインを確認してください。通常なら、URLをキャッシュ対象から除外する機能が内蔵されているはずです。また、ホストも確認してください。キャッシュが自動的に行われるため、サポートの介入が必要になるかもしれません。

    • サーバーがAuth0 Cookieを読み取らない。実行できる解決策については、関連するGitHubの問題を参照しその修正方法を確認してください。

  7. 値がある場合には、読み込まれているコールバックURLの応答ヘッダーを確認します(Chromeで、[View]>[Developer]>[JavaScript Console]>[Network]タブを選択して、リストで最初に出てくる、ステータス500の「document」をクリックして、「Response Headers」を見つけます)。この場所で、max-ageがゼロではないCache-ControlMISS以外のx-cache、このページがキャッシュから提供されていることを示すその他の手がかりなど、キャッシュの証拠がないか確認します。

  8. 応答ヘッダーで、set-cookieauth0_state=deletedのようなディレクティブが含まれていることを確認して、検証プロセスが実行されていることを確認します。

  9. URLのstateパラメーターが、上記の手順3で設定されたCookieのレコードと一致していることを確認します。

  10. キャッシュの証拠が見つからない場合には、wp-config.phpからデバッグ用のスニペットを削除し、コールバックURLをリフレッシュします。「無効な状態」メッセージがまた表示されるはずです。キャッシュに何らかの変更があった場合には、ログイン処理を最後まで試行します(テストする前には必ず、Cookieとブラウザーのキャッシュをクリアしてください)。

以下の手順では、プラグインの変更によってログイン処理が中断されるため、完了後にロールバックが必要になります。これらの手順は必ずテストサーバーまたはステージングサーバーで実行してください。

11.次に、受信する状態が、保管されている値と一致しない理由を確認する必要があります。

12.lib/WP_Auth0_LoginManager.phpで、保管されている状態と返された状態の値を出力してから、処理を停止します。148行目の直前に、以下を追加します。

echo '<h1>$_REQUEST</h1>'; var_dump($_REQUEST); echo '<h1>$_COOKIE</h1>'; var_dump($_COOKIE); die('<h1>Done</h1>');

Was this helpful?

/

13.ログアウトして、ログイン処理が完了したことを確認します。

14.WordPressコールバックURLにリダイレクトで戻された際に、値が出力されるはずです。

15.$_REQUESTstateの値が存在し、$_COOKIEauth0_stateの値と一致しているか確認します。

  • 異なる場合には、上記の手順3で記録された元の値と一致しているはずです。これは、$_COOKIEの状態値が処理中のどこかで変わったということになります。

上記の手順でこの問題が解決されない場合には、上記の手順の結果を集めて、サポートにお問い合わせいただくか、wordpressのタグを付けてコミュニティに投稿してください。また、以下を記載してください。

  • PHPのバージョン

  • WordPressのバージョン

  • Auth0プラグインのバージョン

  • テストに使用したブラウザーとOS

  • ログインフォームを使ってページを読み込むところから、「無効な状態」メッセージを受け取るところまで、処理の全体を記録したHARファイルHARファイルの詳細については、HARファイルの生成と分析をお読みください。

関連する投稿