Repository navigation
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,
?bool $requireUserVerification = null
);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 -
requireUserVerification: constructor override ->PASSKEY_REQUIRE_USER_VERIFICATION
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 and verifies an assertion like completeAuthentication(), but returns the verified user ID without creating a PHP session. Native clients use this before issuing a bearer session.
Consumes registration challenge, validates payload, extracts/stores public key and metadata, and persists a UserPasskey. Native CBOR attestation objects using ES256 or RS256 keys are normalized automatically; browser payloads with an extracted DER public key remain supported.
- Challenges are session-based (
SESSION_KEY = "__pair_passkey_challenges") and single-use. - Challenge expiration defaults to 300 seconds.
- Client data origin must match configured HTTPS origins or an explicitly allowed Android
android:apk-key-hash:<base64url SHA-256 certificate hash>origin. - 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.
Maintained by Viames Marino — VM Ingegneria · Professional enquiries
Home · Setup · Configuration
Build with Pair 4
- Generator
- Controllers and responses
- Read models
- ActiveRecord and queries
- Forms and validation
- PairUI.js and HTML fragments
APIs and authentication
- API guide and CRUD
- Middleware and rate limits
- Users, sessions, and ACL
- Passkeys and social login
- Native mobile setup
Integrate and operate
- Integrations
- Runtime extensions and adapter keys
- Cache and cache stores
- Logs and observability
- PWA and push
- Packages and distribution
- Upgrade to v4