PHPackages                             misakstvanu/laravel-fortify-passkeys - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. misakstvanu/laravel-fortify-passkeys

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

misakstvanu/laravel-fortify-passkeys
====================================

Passkeys backend implementation for Laravel Fortify

v1.0.8-beta(3mo ago)2246[4 PRs](https://github.com/misakstvanu/laravel-fortify-passkeys/pulls)MITPHPPHP ^8.2||^8.3||^8.4

Since Dec 3Pushed 3mo ago3 watchersCompare

[ Source](https://github.com/misakstvanu/laravel-fortify-passkeys)[ Packagist](https://packagist.org/packages/misakstvanu/laravel-fortify-passkeys)[ RSS](/packages/misakstvanu-laravel-fortify-passkeys/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (9)Versions (22)Used By (0)

Warning

This project is currently under development

Laravel Passkeys
================

[](#laravel-passkeys)

This package provides a simple way to authenticate users using passkeys.

Authentication processes are based on `web-auth/webauthn-lib` package. On frontend, the opposite functionality is provided by `@simplewebauthn/browser` package.

Installation
------------

[](#installation)

1. Install the package via composer:

```
composer require misakstvanu/laravel-fortify-passkeys
```

2. Service provider will be auto discovered. If you want to register it manually, add the following line to your `config/app.php`

```
'providers' => [
    /*
     * Package Service Providers...
     */
    // ...
    Misakstvanu\LaravelFortifyPasskeys\PasskeysServiceProvider::class,
];
```

3. Publish migration to create `passkeys` table:

```
php artisan vendor:publish --tag=laravel-fortify-passkeys-migrations
php artisan migrate
```

4. (optional) Publish the config file:

```
php artisan vendor:publish --tag=laravel-fortify-passkeys-config
```

Configuration
-------------

[](#configuration)

1. Implement an interface `Misakstvanu\LaravelFortifyPasskeys\Contracts\PasskeyAuthentication` on your `User` model:

```
use Misakstvanu\LaravelFortifyPasskeys\Models\Contracts\PasskeyAuthentication;

class User extends Authenticatable implements PasskeyAuthentication {
    // ...
}
```

2. Set up `passkeys` relation on your `User` model:

```
use Misakstvanu\LaravelFortifyPasskeys\Models\Passkey;

public function passkeys() :HasMany {
    return $this->hasMany(Passkey::class);
}
```

3. Once you have published the config file, you can configure the package by editing the `config/passkeys.php` file. The variables are:

- `user_model` - the model that will be used to authenticate the user. Default: `App\Models\User`
- `route_prefix` - prefix for the 4 routes this package loads. Default: `passkeys`
- `route_middleware` - middleware that will be applied to the routes. Default: `['web']`
- `username_column` - the column that will be used to find the user. Default: `email`
- `relying_party_ids` - an array of domains that will be allowed insecure connection, use with caution. Default: `[]`
- `registration_user_validation` - validation rules that will be applied to the request when registering new user. These values will then be persisted with the new user. Default: `[]`

### Setting Environment Variables

[](#setting-environment-variables)

To make the configuration more flexible, you can set the configuration values using environment variables. Here are the environment variables you can set:

- `PASSKEYS_USER_MODEL` - the model that will be used to authenticate the user. Default: `App\Models\User`
- `PASSKEYS_ROUTE_PREFIX` - prefix for the 4 routes this package loads. Default: `passkeys`
- `PASSKEYS_ROUTE_MIDDLEWARE` - middleware that will be applied to the routes. Default: `web`
- `PASSKEYS_USERNAME_COLUMN` - the column that will be used to find the user. Default: `email`
- `PASSKEYS_RELYING_PARTY_IDS` - a comma-separated list of domains that will be allowed insecure connection, use with caution. Default: ``
- `PASSKEYS_REGISTRATION_USER_VALIDATION` - a comma-separated list of validation rules that will be applied to the request when registering new user. Default: ``

### Examples

[](#examples)

Here are some examples of how to set the environment variables in your `.env` file:

```
PASSKEYS_USER_MODEL="App\Models\User"
PASSKEYS_ROUTE_PREFIX="passkeys"
PASSKEYS_ROUTE_MIDDLEWARE="web,auth"
PASSKEYS_USERNAME_COLUMN="email"
PASSKEYS_RELYING_PARTY_IDS="example.com,another-example.com"
PASSKEYS_REGISTRATION_USER_VALIDATION="required|string|max:255"
```

Usage
-----

[](#usage)

There are now 6 named routes that make everything work:

`POST 'passkeys.login.start'` - login route, accepts `email` or other field specified in your config. If a user with the given username/email exists and has a passkey registered, credential request options will be returned. If the user does not exist, HTTP 404 will be returned instead.

`POST 'passkeys.login.verify'` - login route, accepts passkey response. If the passkey authentication passes, the user will be logged in. If the passkey authentication fails, an exception with additional information is thrown.

`POST 'passkeys.register.start'` - registration route, accepts `email` or other field specified in your config. Credential request options is returned.

`POST 'passkeys.register.verify'` - registration route, accepts passkey response. If the passkey registration passes, an account will be created from the username/email and any additional data specified in config and sent along with this request. If the passkey registration fails, an exception with additional information is thrown.

`POST 'passkeys.add.options'` - add passkey route, generates options to add a new passkey to a logged-in user.

`POST 'passkeys.add'` - add passkey route, accepts passkey response. If the passkey registration passes, the passkey will be added to the existing account. If the passkey registration fails, an exception with additional information is thrown.

JS Example
----------

[](#js-example)

Below is minimal example of how to use this package with js `@simplewebauthn/browser`.

```
import {browserSupportsWebAuthn, startAuthentication, startRegistration} from "@simplewebauthn/browser";
//import 'api' object based on axios and configured with our app url

function base64ToArrayBuffer(base64) {
    const binaryString = atob(base64)
    const len = binaryString.length
    const bytes = new Uint8Array(len)
    for (let i = 0; i  {
            // Decode the challenge before passing to startRegistration
            if (response.data.challenge) {
                response.data.challenge = base64ToArrayBuffer(response.data.challenge)
            }
            startRegistration(response.data)
        })
        // Verify the data with the server
        .then((attResp) => api.post('/passkey/register', attResp))
        .then((verificationResponse) => {
            if (verificationResponse.data?.verified) {
                // WE ARE REGISTERED AND LOGGED IN / PASSKEY WAS ASSOCIATED WITH NEW OR LOGGED IN ACCOUNT
                return window.location.reload();
            }
            // Something went wrong verifying the registration.
        })
        .catch((error) => {
            // Handle error information
        });
}
function login() {
    // Ask for the authentication options
    api.post('/passkey/login/options', {
            email: 'your@email.com',
        })
        // Prompt the user to authenticate with their passkey
        .then((response) => {
            // Decode the challenge before passing to startRegistration
            if (response.data.challenge) {
                response.data.challenge = base64ToArrayBuffer(response.data.challenge)
            }
            startAuthentication(response.data)
        })
        // Verify the data with the server
        .then((attResp) =>
            api.post('/passkey/login', attResp),
        )
        .then((verificationResponse) => {
            if (verificationResponse.data?.verified) {
                // WE ARE LOGGED IN
                return window.location.reload();
            }
            // Something went wrong verifying the authentication.
        })
        .catch((error) => {
            // Handle error information
        });
}
function addPasskey() {
    // Ask for the options to add a new passkey
    api.post('/passkey/add/options')
        // Prompt the user to create a passkey
        .then((response) => startRegistration(response.data))
        // Verify the data with the server
        .then((attResp) => api.post('/passkey/add', attResp))
        .then((verificationResponse) => {
            if (verificationResponse.data?.verified) {
                // PASSKEY WAS ADDED TO THE EXISTING ACCOUNT
                return window.location.reload();
            }
            // Something went wrong verifying the registration.
        })
        .catch((error) => {
            // Handle error information
        });
}
```

Refactoring
-----------

[](#refactoring)

The code has been refactored to reduce duplication and follow Laravel best practices. A new service class `PasskeyService` has been created to handle common logic for generating options and verifying responses. The `generateOptions` and `verify` methods in `AddPasskeyController`, `RegistrationController`, and `AuthenticationController` have been refactored to use `PasskeyService`.

### PasskeyService

[](#passkeyservice)

The `PasskeyService` class is located in `src/Services/PasskeyService.php`. It contains the following methods:

- `generateOptions(Request $request, $user = null): array` - Generates options for passkey creation.
- `verify(Request $request, ServerRequestInterface $serverRequest, $user = null): array` - Verifies the passkey response.

### Controllers

[](#controllers)

The `generateOptions` and `verify` methods in the following controllers have been refactored to use `PasskeyService`:

- `AddPasskeyController`
- `RegistrationController`
- `AuthenticationController`

The `PasskeyService` is injected into the constructors of these controllers and used to handle the common logic for generating options and verifying responses.

### Response Array

[](#response-array)

The response has been updated to return an array with "verified". This change has been applied to the `verify` methods in the `AddPasskeyController`, `RegistrationController`, and `AuthenticationController`. The updated response is as follows:

```
if ($response['verified']) {
    return ['verified' => true];
}

return ['verified' => false];
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance80

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~87 days

Recently: every ~100 days

Total

10

Last Release

106d ago

PHP version history (3 changes)v1.0.1-alphaPHP ^8.2

v1.0.3-betaPHP ^8.2||^8.3

v1.0.8-betaPHP ^8.2||^8.3||^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/6bc48954dcd166e31a15e1a5da3e253b5ae1b4ba0031e391de4ccfdecef04c91?d=identicon)[misakstvanu](/maintainers/misakstvanu)

---

Top Contributors

[![misakstvanu](https://avatars.githubusercontent.com/u/42741294?v=4)](https://github.com/misakstvanu "misakstvanu (45 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/misakstvanu-laravel-fortify-passkeys/health.svg)

```
[![Health](https://phpackages.com/badges/misakstvanu-laravel-fortify-passkeys/health.svg)](https://phpackages.com/packages/misakstvanu-laravel-fortify-passkeys)
```

###  Alternatives

[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[craftcms/cms

Craft CMS

3.6k3.6M2.6k](/packages/craftcms-cms)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[web-auth/webauthn-lib

FIDO2/Webauthn Support For PHP

1195.3M72](/packages/web-auth-webauthn-lib)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
