-
Notifications
You must be signed in to change notification settings - Fork 2
PasskeyAuth
Pair\Services\PasskeyAuth implements Passkey/WebAuthn registration and authentication flows.
It manages challenge lifecycle, verifies WebAuthn payloads, persists credentials, and finalizes login.
new \Pair\Services\PasskeyAuth(
?string $rpId = null,
?string $rpName = null,
?array $allowedOrigins = null,
int $challengeTtl = 300
);Resolution order:
-
rpId: constructor arg ->PASSKEY_RP_ID-> host fromBASE_HREF/HTTP_HOST -
rpName: constructor arg ->PASSKEY_RP_NAME->APP_NAME->"Pair App" -
allowedOrigins: constructor arg ->PASSKEY_ALLOWED_ORIGINS->BASE_HREF
If RP ID or allowed origins are missing, it throws PairException(MISSING_CONFIGURATION).
Creates publicKey options for navigator.credentials.get(...).
If $user is passed and no allow-list is provided, active user passkeys are loaded automatically.
beginRegistration(User $user, ?string $userDisplayName = null, array $excludeCredentialIds = [], array $options = []): array
Creates publicKey options for navigator.credentials.create(...).
By default excludes already active credentials of the same user.
Consumes challenge, validates assertion (type, challenge, origin, RP ID hash, signature, counter), then returns the output of User::doLoginById(...).
On failure it returns a standard failed-login object (error=true, message, userId=null, sessionId=null) and logs failed attempts via Audit::loginFailed(...).
Consumes registration challenge, validates payload, extracts/stores public key and metadata, and persists a UserPasskey.
- Challenges are session-based (
SESSION_KEY = "__pair_passkey_challenges") and single-use. - Challenge expiration defaults to 300 seconds.
- Client data origin must match configured allowed origins.
- Signature verification requires OpenSSL (
openssl_verify/openssl_pkey_get_public). - Counter rollback is rejected during authentication.
- Optional user verification enforcement is driven by
PASSKEY_REQUIRE_USER_VERIFICATION.
Authentication:
-
idorrawId response.clientDataJSONresponse.authenticatorDataresponse.signature
Registration:
-
idorrawId response.clientDataJSON-
response.publicKeyPemorresponse.publicKey(base64url DER SPKI)
PASSKEY_RP_IDPASSKEY_RP_NAME-
PASSKEY_ALLOWED_ORIGINS(comma-separated) PASSKEY_REQUIRE_USER_VERIFICATION
See also: PasskeyController, UserPasskey, User, Session, Audit, PairPasskey.js.