---
title: "Rozšírenie — Passkeys for Laravel | Roundly"
description: "Vymeňte úložisko challenge, pridajte formát atestácie, nahraďte politiku dôvery alebo implementujte HasPasskeys sami — cez väzby v kontajneri."
url: https://roundly-consulting.com/sk/open-source/navody/passkeys-for-laravel/rozsirenie
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Passkeys for Laravel](https://roundly-consulting.com/sk/open-source/navody/passkeys-for-laravel.md)

# Rozšírenie

Service provider viaže každý kontrakt na predvolený singleton. Naviažte vlastnú implementáciu a vymení sa všade:

| Kontrakt | Predvolená väzba | Účel |
| --- | --- | --- |
| `PasskeyService` | PasskeyManager | Koreň fasády — for($user), ceremónia bez mena a attestationFormats(). |
| `ChallengeRepository` | CacheChallengeRepository | Jednorazové úložisko challenge s TTL. |
| `AttestationVerifier` | AttestationGate | Politika dôvery atestácie — rebríček, kotvy, allowlist AAGUID. |
| `HasPasskeys` | Váš model cez InteractsWithPasskeys | Model, ktorý vlastní prístupové kľúče. |

Namiesto výmeny celej služby radšej previažte jednu akciu (napríklad RevokePasskeyAction) — manažér aj handle účtu získavajú každú akciu z kontajnera, takže zmena platí pre fasádu, injektovanú službu aj metódy modelu. Úplne vlastný PasskeyService implementuje štyri metódy — for($user), ktorá vracia handle UserPasskeys, authenticationOptions(?$overrides), authenticate($response, ?$expect) a attestationFormats().

## Vlastné úložisko challenge

CacheChallengeRepository ukladá každú challenge pod passkeys:challenge:<ceremonyId> v cache store-e podľa challenge.store a pull() ju načíta a zmaže pod zámkom store-u, takže z dvoch súbežných požiadaviek na jednu ceremóniu ju dostane práve jedna. Ak chcete challenge ukladať inde, implementujte kontrakt a naviažte ho:

```php
use RoundlyConsulting\Passkeys\Contracts\ChallengeRepository;
use RoundlyConsulting\Passkeys\DataTransferObjects\ChallengeData;

final class DatabaseChallengeRepository implements ChallengeRepository
{
    public function put(string $ceremonyId, ChallengeData $challenge, int $ttl): void { /* … */ }
    public function pull(string $ceremonyId): ?ChallengeData { /* fetch + delete atomically */ }
}

// In a service provider:
$this->app->singleton(ChallengeRepository::class, DatabaseChallengeRepository::class);
```

pull() musí vrátiť null, ak challenge chýba, vypršala alebo už bola spotrebovaná, a musí zostať jednorazová aj pri súbežnosti — samotné načítanie a následné samostatné zmazanie nestačí.

## Pridanie formátu atestácie

Atestácia je rozdelená na dve časti. Overovače formátov dokazujú len matematiku a vracajú AttestationResult; o dôvere rozhoduje výhradne AttestationGate — rebríček, prepojenie reťazca, platnosť, kotvy aj allowlist AAGUID. Napíšte overovač:

```php
use RoundlyConsulting\Crypto\Cose\AuthenticatorData;
use RoundlyConsulting\Passkeys\Attestation\AttestationResult;
use RoundlyConsulting\Passkeys\Attestation\AttestationVerifier;
use RoundlyConsulting\Passkeys\DataTransferObjects\AttestationObject;
use RoundlyConsulting\Passkeys\Enums\AttestationType;

final class AndroidSafetynetVerifier implements AttestationVerifier
{
    public function verify(
        AttestationObject $attestation,
        AuthenticatorData $authenticatorData,
        string $clientDataHash,
    ): AttestationResult {
        // Prove the maths; throw InvalidAttestation on any failure. Never rule on
        // trust — the gate owns that. Your own reason text is kept verbatim:
        // InvalidAttestation::malformedStatement('android-safetynet', 'the JWS is not compact')
        return AttestationResult::chained('android-safetynet', AttestationType::Basic, $chain);
    }
}
```

Potom znovu naviažte register s pridaným overovačom — všetky rozhodnutia o dôvere zostávajú v gate:

```php
use Illuminate\Contracts\Foundation\Application;
use RoundlyConsulting\Passkeys\Attestation\AppleAttestationVerifier;
use RoundlyConsulting\Passkeys\Attestation\AttestationVerifierRegistry;
use RoundlyConsulting\Passkeys\Attestation\NoneAttestationVerifier;
use RoundlyConsulting\Passkeys\Attestation\PackedAttestationVerifier;
use RoundlyConsulting\Passkeys\Support\CredentialCrypto;

// In a service provider:
$this->app->singleton(AttestationVerifierRegistry::class, fn (Application $app) => new AttestationVerifierRegistry([
    'none' => new NoneAttestationVerifier,
    'packed' => new PackedAttestationVerifier($app->make(CredentialCrypto::class)),
    'apple' => new AppleAttestationVerifier,
    'android-safetynet' => new AndroidSafetynetVerifier,
]));
```

Reťazce certifikátov skladajte zo surových DER bajtov, ktoré nesie CBOR, nikdy nie z base64 pomocníka pre x5c — ten zodpovedá tvaru JOSE a odmietol by každý skutočný autentifikátor. Ak chcete celú politiku atestácie nahradiť, naviažte vlastný AttestationVerifier; ceremónia volá len ten.

## Vlastné napojenie používateľa

Ak potrebujete špecifické ukladanie identifikátora alebo odvodenie mena, implementujte HasPasskeys priamo namiesto traitu. Ceremónie potrebujú len štyri metódy kontraktu — dbajte len na to, aby passkeyUserHandle() zostal stabilný.

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/passkeys-for-laravel.md)
