---
title: "Prihlásenie — Passkeys for Laravel | Roundly"
description: "Prihlásenie bez mena alebo viazané na používateľa — pripravte možnosti, overte podpis a zo získaného kľúča spustite vlastnú session."
url: https://roundly-consulting.com/sk/open-source/navody/passkeys-for-laravel/prihlasenie
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)

# Prihlásenie

Aj prihlásenie sú dve volania — možnosti smerom von, podpísaná odpoveď dnu. Balík nájde kľúč a jeho vlastníka; session alebo token potom vydá vaša aplikácia:

```php
use RoundlyConsulting\Passkeys\Facades\Passkeys;
use RoundlyConsulting\Passkeys\DataTransferObjects\AuthenticationResponseData;

// 1. Server -> client: request options (usernameless — any account's passkey can answer).
$options = Passkeys::authenticationOptions();      // or Passkeys::for($user)->authenticationOptions()
return response()->json($options);                 // the browser parses publicKey for navigator.credentials.get()

// 2. Client -> server: verify the assertion; the resolved credential's owner is reachable
//    via $passkey->authenticatable. The host then issues its own session or token.
$passkey = Passkeys::authenticate(
    AuthenticationResponseData::fromArray($request->validated()),
);
$user = $passkey->authenticatable;
```

## Bez mena alebo viazané na používateľa

- Bez používateľa — allowCredentials je prázdne, takže autentifikátor ponúkne ľubovoľný objaviteľný kľúč pre vašu RP a nahlási jeho identifikátor používateľa. Odpoveď musí tento userHandle obsahovať (WebAuthn §7.2, krok 6); odpoveď bez neho dostane jednotné CredentialNotFound.
- S používateľom, cez Passkeys::for($user)->authenticationOptions() — allowCredentials obsahuje kľúče tohto používateľa a ceremónia je na ne viazaná: dokončiť ju môže len ponúknutý kľúč. Kľúč iného účtu alebo kľúč pridaný až po vydaní možností dostane rovnakú jednotnú odpoveď CredentialNotFound ako neznámy kľúč.

authenticationOptions() vracia RequestOptionsData, ktorý sa serializuje do JSON formy WebAuthn — publicKey je PublicKeyCredentialRequestOptionsJSON s binárnymi položkami v base64url. Prehliadač ho pred navigator.credentials.get() prevedie cez PublicKeyCredential.parseRequestOptionsFromJSON() a ceremonyId sa vracia spolu s odpoveďou, aby bezstavová aplikácia vedela priradiť challenge:

```json
{
  "ceremonyId": "…40 chars…",
  "publicKey": {
    "challenge": "…b64url…",
    "rpId": "example.com",
    "timeout": 60000,
    "userVerification": "required",
    "allowCredentials": []
  }
}
```

## Na strane prehliadača

Rovnaké kroky ako pri registrácii, len s parseRequestOptionsFromJSON() a navigator.credentials.get() — credential.toJSON() pošlite späť spolu s ceremonyId:

```js
const options = await (await fetch('/login/passkey/options')).json();
const credential = await navigator.credentials.get({
    publicKey: PublicKeyCredential.parseRequestOptionsFromJSON(options.publicKey),
});
await fetch('/login/passkey', { method: 'POST', headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ...credential.toJSON(), ceremonyId: options.ceremonyId }) });
```

credential.toJSON() ceremonyId neobsahuje, preto ho pridá frontend; bez neho ceremónia zlyhá výnimkou ChallengeExpired. Starším prehliadačom parseRequestOptionsFromJSON() aj toJSON() chýbajú: tam, kde chýbajú, pred volaním preveďte challenge a každé allowCredentials\[\].id z base64url na ArrayBuffer a pred odoslaním zakódujte rawId a položky response do base64url.

## Prihlásenie používateľa

AuthenticationResponseData::fromArray() načíta rawId (alebo id), ceremonyId, response.clientDataJSON, response.authenticatorData, response.signature a voliteľný response.userHandle. Balík nikoho neprihlasuje — to zostáva na vás:

```php
use RoundlyConsulting\Passkeys\DataTransferObjects\AuthenticationResponseData;

$response = AuthenticationResponseData::fromArray($request->all());
$passkey  = Passkeys::authenticate($response);          // Passkey

// The host owns login — start its own session/token:
Auth::login($passkey->authenticatable);
```

## Čo overí authenticate()

- Kľúč sa vyhľadá podľa ID; každý neúspech je jednotné CredentialNotFound, takže registrovaných používateľov nemožno zistiť. Ak príde userHandle, musí sa zhodovať s uloženým (porovnanie v konštantnom čase).
- Kľúč musí stále patriť svojmu vlastníkovi — overí sa to pred spotrebovaním challenge a pred akýmkoľvek zápisom. Vlastník musí stále existovať (natrvalo zmazaný ani zmazaný cez soft delete neprejde) a jeho uložený identifikátor používateľa sa musí zhodovať s identifikátorom kľúča (porovnanie v konštantnom čase), takže účet, ktorý dostane ID zmazaného účtu, jeho kľúče nikdy nezdedí. Typ vlastníka, ktorý už neoznačuje konkrétny model — premenovaná trieda účtu, morph alias vyradený z mapy, abstraktný model — sa berie ako chýbajúci vlastník, nikdy nie ako surový Error; takéto kľúče obnovíte namapovaním starého typu na aktuálnu triedu. Každý takýto neúspech je jednotné CredentialNotFound.
- Ak ste zadali AuthenticationExpectation, overí sa hneď potom — ešte pred spotrebovaním challenge a pred akýmkoľvek zápisom.
- clientDataJSON sa dá dekódovať a jeho typ je webauthn.get.
- Challenge bola vydaná pre prihlásenie a zhoduje sa v konštantnom čase; pri challenge viazanej na používateľa musí kľúč patriť tomuto používateľovi a byť medzi ponúknutými a pri challenge bez mena musí odpoveď obsahovať userHandle.
- Allowlist originov a cross-origin politika sú splnené.
- Hash RP ID sa zhoduje; prítomnosť používateľa je nastavená, overenie používateľa tiež, ak ho ceremónia vyžaduje, zálohovaný kľúč je na zálohu oprávnený a oprávnenosť na zálohu sa stále zhoduje s hodnotou uloženou pri registrácii (WebAuthn L3 §7.2, krok 19).
- Podpis nad authenticatorData ‖ sha256(clientDataJSON) sa overí uloženým verejným kľúčom.
- Zosúladí sa počítadlo podpisov, zaznamená sa stav zálohy a spustí sa PasskeyAuthenticated.

## Zosúladenie počítadla podpisov

sign\_count chráni pred klonovanými autentifikátormi. Počítadlo sa posúva vždy len dopredu a rozhoduje databáza: posun je jeden podmienený UPDATE … WHERE sign\_count < ?, takže nižšiu hodnotu nezapíše späť ani pokles, ani dva súbežné podpisy. Pri každom úspešnom podpise:

- Vyššia hodnota posunie sign\_count; stav zálohy z podpisu a last\_used\_at sa zapíšu v tom istom príkaze.
- Ak je uložená aj prijatá hodnota 0 (autentifikátory bez počítadla), použitie sa zaznamená — no len kým je uložená hodnota stále 0.
- Ak sa počítadlo neposunulo, rozhoduje sign\_count\_policy: reject vyhodí SignCountRegression a prihlásenie preruší; flag (predvolené) spustí PasskeySignCountRegressed, zapíše stav zálohy a last\_used\_at bez zmeny počítadla a prihlásenie pustí.
- Uložená hodnota sa nikdy nezníži, takže pri flag sa klonovaný autentifikátor označí pri každom svojom podpise, nielen pri prvom.
- Kľúč odvolaný počas overovania podpisu skončí výnimkou CredentialNotFound.

## Priame použitie akcií

Volania bez mena aj volania viazané na používateľa zdieľajú tie isté dve akcie; používateľ aj očakávanie sú voliteľné (pozri DI a akcie):

```php
use RoundlyConsulting\Passkeys\Actions\GenerateAuthenticationOptionsAction;
use RoundlyConsulting\Passkeys\Actions\VerifyAuthenticationAction;

$options = app(GenerateAuthenticationOptionsAction::class)->execute($user, $overrides); // both optional
$passkey = app(VerifyAuthenticationAction::class)->execute($response, $expectation);  // expectation optional
```

## 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)
