Message d’erreur
Unexpected registration response origin "http://localhost:3000", expected "https://app.example.com"
Également affiché sous la forme
- Unexpected authentication response origin "http://localhost:3000", expected "https://app.example.com"
- Unexpected registration response challenge "b3RoZXI", expected "c2VydmVyLWNoYWxsZW5nZS0xMjM"
La première valeur entre guillemets est l’origine signalée par le navigateur, la seconde celle de votre configuration. Lors de la connexion, le texte indique « authentication response » ; un challenge discordant produit « Unexpected registration response challenge … » dans la même bibliothèque.
SimpleWebAuthn (@simplewebauthn/server) — verifyRegistrationResponse / verifyAuthenticationResponse
Ce que cela signifie
Le navigateur a enregistré l’origine de la page dans `clientDataJSON` (les données que l’authentificateur signe), et elle diffère de la valeur `expectedOrigin` que votre serveur a passée à SimpleWebAuthn. Ce contrôle existe pour empêcher qu’une cérémonie portant sur un identifiant, effectuée sur un site (par exemple une imitation créée pour l’hameçonnage), soit acceptée par un autre. L’authentificateur n’y est pour rien : l’idée que se fait le serveur de l’endroit où se trouvent ses pages ne correspond pas à l’endroit où la cérémonie s’est réellement déroulée.
Pourquoi cela se produit
Origine de production configurée en développement (ou l’inverse)
fréquente`expectedOrigin` codé en dur sur l’URL de production pendant les tests sur `http://localhost:3000`, sur un déploiement de prévisualisation ou sur l’URL d’un tunnel (ngrok, Cloudflare Tunnel).
La page de connexion est servie depuis plusieurs origines
fréquente`www.` et le domaine apex, plusieurs domaines nationaux, ou un sous-domaine `accounts.` distinct. Chaque origine qui peut exécuter la cérémonie doit figurer dans la liste.
Une application Android native
occasionnelleCredential Manager (le Gestionnaire d’identifiants d’Android) indique `android:apk-key-hash:…` comme origine, et non votre origine web. Le condensat de la clé de signature de l’application doit figurer dans `expectedOrigin`.
Comment corriger l’erreur
- 1.
Lister explicitement chaque origine légitime
`expectedOrigin` accepte un tableau. Limitez-le aux origines que vous contrôlez ; n’acceptez jamais l’origine fournie par la requête elle-même.
js const verification = await verifyRegistrationResponse({ response: body, expectedChallenge: session.currentChallenge, // Every origin that legitimately hosts your sign-up page, exactly as browsers report it: expectedOrigin: ["https://app.example.com", "https://www.example.com"], expectedRPID: "example.com", }); - 2.
Ajouter l’origine de l’application Android
Calculez le SHA-256 en base64url du certificat de signature de l’application et ajoutez-le sous la forme `android:apk-key-hash:`.
js // Android apps report "android:apk-key-hash:<base64url SHA-256 of the app signing certificate>". // SHA-256 fingerprint from Play Console or: keytool -list -v -keystore release.jks | grep SHA256 const fingerprintHex = process.env.ANDROID_SIGNING_CERT_SHA256.replaceAll(":", ""); const androidOrigin = "android:apk-key-hash:" + Buffer.from(fingerprintHex, "hex").toString("base64url"); const verification = await verifyRegistrationResponse({ response: body, expectedChallenge: session.currentChallenge, expectedOrigin: ["https://example.com", androidOrigin], expectedRPID: "example.com", });