Skip to content

PasskeyController

Viames Marino edited this page Apr 20, 2026 · 2 revisions

Pair framework: PasskeyController

Pair\Api\PasskeyController is an API base controller that exposes ready-to-use Passkey/WebAuthn endpoints.

It extends CrudController, so you can use passkey endpoints and CRUD resources in the same API module.

Quick usage

<?php

namespace App\Modules\Api;

class ApiController extends \Pair\Api\PasskeyController {}

Built-in endpoints

  • POST /api/passkey/login/options
  • POST /api/passkey/login/verify
  • POST /api/passkey/register/options (requires auth session)
  • POST /api/passkey/register/verify (requires auth session)
  • GET /api/passkey/list (requires auth session)
  • DELETE /api/passkey/revoke/{id} (requires auth session)

Behavior notes

  • Login flows can be usernameless or can receive username in payload.
  • Registration and management endpoints use the ApiController auth guard and now bubble UNAUTHORIZED as an explicit ApiErrorResponse on the migrated v4 path.
  • Challenge creation/verification is delegated to Pair\Services\PasskeyAuth.
  • passkeyAction() routes by URL params and HTTP method; unknown combinations now return an explicit ApiErrorResponse.
  • All built-in passkey success endpoints now return explicit JsonResponse objects on the migrated v4 path, including GET /api/passkey/list and DELETE /api/passkey/revoke/{id}.
  • Method, media-type, body-shape, credential, and revoke validation errors now bubble as explicit ApiErrorResponse objects on migrated passkey action paths.

Payload shapes

Login options request

{ "username": "john" }

username is optional.

Login verify request

{
  "credential": { "...": "serialized WebAuthn assertion" },
  "username": "john",
  "timezone": "Europe/Rome"
}

username and timezone are optional (timezone defaults to UTC if invalid/missing).

Register options request

{ "displayName": "John Doe" }

displayName is optional.

Register verify request

{
  "credential": { "...": "serialized WebAuthn attestation" },
  "label": "My MacBook"
}

label is optional.

Typical responses

  • Login verify success:
    • message, userId, sessionId
  • Register verify success (201):
    • message, passkey object (id, label, credentialId, createdAt)
  • List success:
    • array of passkeys (id, label, credentialId, createdAt, lastUsedAt, transports)
  • Revoke success:
    • HTTP 204 No Content
  • Guard or payload failure:
    • standard Pair API error payload with code and error

See also: API, ApiController, CrudController, PasskeyAuth, UserPasskey, PairPasskey.js.

Clone this wiki locally