エラーメッセージ
SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current domain. Subsequently, an attempt to fetch the .well-known/webauthn resource of the claimed RP ID failed.
別の表記
- SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current domain.
関連オリジンリクエストに対応していない Chromium のバージョンでは、文が「…nor equal to the current domain.」で終わります。ほかのブラウザーでは文言が異なり、変わらないのは DOMException の名前 `SecurityError` です。
WebAuthn navigator.credentials.create() / get() — DOMException SecurityError (Chromium)
このエラーの意味
オプションで指定した RP ID が、ページ自身のホスト名でも、その登録可能な親ドメインでもないため、ブラウザーはその RP ID での認証情報の作成も使用も拒否しました。パスキーは RP ID に紐付いています。どのページでも任意の RP ID を名乗れるとしたら、あるサイトが別のサイトのパスキーを使えてしまいます。Chromium は WebAuthn の関連オリジンリクエスト(Related Origin Requests)の仕組み、つまり `https://<rp-id>/.well-known/webauthn` を取得して RP ID がこのページのオリジンを列挙しているかを確認する方法も試しましたが、それでもリクエストは許可されませんでした。
発生する理由
開発用またはプレビュー用のホストに本番環境の RP ID が設定されている
よくある`rp.id: "app.example.com"` が、`localhost` 上のページ、プレビューデプロイの URL(`*.vercel.app`、`*.netlify.app`)、ステージング用のドメインに送られています。RP ID は、ページを配信している環境と一致していなければなりません。
兄弟ドメインや子ドメインを RP ID にしている
よくある`login.example.com` 上のページは `login.example.com` または `example.com` を使えますが、`app.example.com` や `api.login.example.com` は使えません。最初から親ドメインを選んでおけば、すべてのサブドメインでパスキーを共有できます。
.well-known/webauthn に記載のない別のドメイン
ときどき異なるドメイン(国別 TLD、ブランド変更後のドメインなど)で 1 つの RP ID を使うには、RP ID のドメインの `/.well-known/webauthn` にほかのオリジンを列挙しておく必要があります。これがない場合や、このファイルに到達できない場合、リクエストは拒否されます。
IP アドレスでサイトを開いている
ときどきIP アドレスは有効な RP ID ではありません。WebAuthn にはドメイン名が必要です(開発時は `localhost` を使えます)。
修正方法
- 1.
環境ごとに RP ID を設定する
RP ID と想定するオリジンを環境ごとの設定にまとめ、開発、プレビュー、本番がそれぞれ自身のホストを使うようにしてください。また、パスキーは別の RP ID に引き継がれないことも覚えておいてください。
js // Server: derive the RP ID from configuration per environment, never hard-code production. const rpID = process.env.WEBAUTHN_RP_ID; // "localhost" in dev, "example.com" in production const expectedOrigin = process.env.WEBAUTHN_ORIGIN; // "http://localhost:3000" / "https://app.example.com" const options = await generateRegistrationOptions({ rpName: "Example", rpID, userName }); - 2.
関連オリジンは意図的に公開する
複数のドメインでパスキーを共有しなければならない場合は、それらのドメインを列挙した `/.well-known/webauthn` を RP ID のドメインで配信してください(現行の Chromium と Safari が対応しています)。
json // https://example.com/.well-known/webauthn (served as application/json) { "origins": ["https://example.co.uk", "https://example-shop.com"] }
関連するエラー
NotAllowedError: The operation either timed out or was not allowed. See: https:…WebAuthn navigator.credentials.get() / create()Unexpected registration response origin "http://localhost:3000", expected "http…SimpleWebAuthn (@simplewebauthn/server)TypeError: Cannot read properties of undefined (reading 'digest')WebCrypto