PHP code example of padosoft / laravel-rebel-bridge-passkeys

1. Go to this page and download the library: Download padosoft/laravel-rebel-bridge-passkeys library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

padosoft / laravel-rebel-bridge-passkeys example snippets


use Padosoft\Rebel\Bridge\Passkeys\Challengers\SpatiePasskeyChallenger;
use Padosoft\Rebel\Bridge\Passkeys\Contracts\PasskeyChallenger;

public function register(): void
{
    $this->app->singleton(PasskeyChallenger::class, SpatiePasskeyChallenger::class);
}

use Spatie\LaravelPasskeys\Models\Concerns\HasPasskeys;
use Spatie\LaravelPasskeys\Models\Passkeys\HasPasskeysTrait;

class User extends Authenticatable implements HasPasskeys
{
    use HasPasskeysTrait;

    // ...
}

use App\WebAuthn\MyWebAuthnChallenger;
use Padosoft\Rebel\Bridge\Passkeys\Contracts\PasskeyChallenger;

$this->app->singleton(PasskeyChallenger::class, MyWebAuthnChallenger::class);

interface PasskeyChallenger
{
    // Does this user have at least one passkey registered?
    public function hasPasskey(Authenticatable $user): bool;

    // Issue a fresh single-use challenge. Return an opaque string (the nonce,
    // or serialised WebAuthn options JSON) that you can later pass to verifyAssertion().
    public function startChallenge(Authenticatable $user): string;

    // Verify the assertion (JSON from navigator.credentials.get()) against
    // the challenge issued by startChallenge(). Return true on full success.
    public function verifyAssertion(Authenticatable $user, string $assertion, string $challenge): bool;
}

// routes/web.php
Route::post('/account/delete', [AccountController::class, 'destroy'])
    ->middleware(['auth', 'rebel.stepup:delete-account']);

// config/rebel-step-up.php
'purposes' => [
    'delete-account' => [
        '],
    ],
],

use Padosoft\Rebel\StepUp\RebelStepUp;
use Padosoft\Rebel\StepUp\StepUpContext;
use Padosoft\Rebel\Core\Context\SecurityContext;

class PaymentController extends Controller
{
    public function confirm(Request $request, RebelStepUp $stepUp): JsonResponse
    {
        $context = new StepUpContext(
            subject: $request->user(),
            purpose: 'confirm-payment',
            security: SecurityContext::fromRequest($request, app(KeyedHasher::class)),
        );

        // Start the step-up: issues a WebAuthn challenge.
        $result = $stepUp->start($context, driver: 'passkeys');

        return response()->json([
            'challenge_reference' => $result->reference,
            'webauthn_options' => $result->options,
        ]);
    }

    public function verify(Request $request, RebelStepUp $stepUp): JsonResponse
    {
        $context = new StepUpContext(
            subject: $request->user(),
            purpose: 'confirm-payment',
            security: SecurityContext::fromRequest($request, app(KeyedHasher::class)),
        );

        $verified = $stepUp->verify(
            $context,
            input: $request->input('assertion'),      // JSON from navigator.credentials.get()
            reference: $request->input('reference'),  // reference from start()
        );

        if (! $verified) {
            return response()->json(['error' => 'Step-up failed'], 422);
        }

        // Proceed with the protected action.
        $this->processPayment($request);

        return response()->json(['status' => 'confirmed']);
    }
}

use Padosoft\Rebel\StepUp\DriverRegistry;
use Padosoft\Rebel\StepUp\StepUpContext;

$driver = app(DriverRegistry::class)->get('passkeys');

if ($driver && $driver->isAvailableFor($context)) {
    // Show the "Use passkey" button.
}

use Padosoft\Rebel\Bridge\Passkeys\Contracts\PasskeyChallenger;
use Padosoft\Rebel\Bridge\Passkeys\Testing\FakePasskeyChallenger;

// In your test boot or TestCase::defineEnvironment():
$app->singleton(PasskeyChallenger::class, fn () => new FakePasskeyChallenger(
    registered: true,           // user has a passkey
    expectedAssertion: 'valid', // the assertion string that will be accepted
    challenge: 'test-nonce',    // the challenge returned by startChallenge()
));

// All step-up driver logic works offline without any WebAuthn ceremony.
bash
composer vendor:publish --tag="passkeys-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="rebel-bridge-passkeys-config"

src/
  Challengers/
    SpatiePasskeyChallenger.php   # Production adapter for spatie/laravel-passkeys
  Contracts/
    PasskeyChallenger.php         # The seam: swap the WebAuthn library here
  Drivers/
    PasskeysStepUpDriver.php      # Core driver (key:'passkeys', AAL2, phishing-resistant)
  Testing/
    FakePasskeyChallenger.php     # Deterministic test double
  RebelPasskeysBridgeServiceProvider.php
config/
  rebel-bridge-passkeys.php       # drivers.passkeys toggle
tests/
  Feature/
    PasskeysDriverTest.php        # 17 tests covering all paths