Git Product home page Git Product logo

laravel-webauthn's Introduction

Webauthn adapter for Laravel

Latest Version Downloads Workflow Status Quality Gate Coverage Status

LaravelWebauthn is the adapter to use Webauthn as 2FA (two-factor authentication) or as passwordless authentication on Laravel.

Try this now on the demo application.

Features

  • Manage Webauthn keys registration
  • 2nd factor authentication: add a middleware service to use a Webauthn key as 2FA
  • Login provider using a Webauthn key, without password

Installation

Install this package with:

composer require asbiin/laravel-webauthn

Configuration

You can publish LaravelWebauthn configuration in a file named config/webauthn.php, and resources using the vendor:publish command:

php artisan vendor:publish --provider="LaravelWebauthn\WebauthnServiceProvider"

Next, you should migrate your database:

php artisan migrate

Set Up

Option 1: add LaravelWebauthn middleware

The Webauthn middleware will force the user to authenticate their webauthn key for certain routes.

Assign the middleware to a route or a group of routes:

use LaravelWebauthn\Http\Middleware\WebauthnMiddleware;

Route::get('/home', function () {
    // ...
})->middleware(WebauthnMiddleware::class);

The Webauthn middleware will redirect the user to the webauthn login page when required.

Login via remember

When session expires, but the user have set the remember cookie, you can revalidate webauthn session by subscribing to the LaravelWebauthn\Listeners\LoginViaRemember listener:

use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Event::listen(
            \Illuminate\Auth\Events\Login::class,
            \LaravelWebauthn\Listeners\LoginViaRemember::class
        );
    }
}

Option 2: Passwordless authentication

You can use Webauthn to authenticate a user without a password, using only a webauthn key authentication.

To enable passwordless authentication, first add the webauthn user provider: update your config/auth.php file and change the users provider:

'providers' => [
    'users' => [
        'driver' => 'webauthn',
        'model' => App\Models\User::class,
    ],
],

Then allow your login page to initiate a webauthn login with an email identifier.

You can call webauthn.auth.options route with a POST request and an email input to get the challenge data. See authentication section for more details.

Disabling Views

By default LaravelWebauthn defines routes that are intended to return views for authentication and register key.

However, if you are building a JavaScript driven single-page application, you may not need these routes. For that reason, you may disable these routes entirely by setting the views configuration value within your application's config/webauthn.php configuration file to false:

'views' => false,

Cache

Note this package uses the cache to store the challenge data between the server request and the browser response. You'll need to setup a real cache driver from your config/cache.php file, and thus you can't use the array or null driver.

Usage

You will find an example of usage on asbiin/laravel-webauthn-example. You can try it right now on the demo application.

Authenticate

To authenticate with a webauthn key, the workflow is the following:

  1. Open the webauthn.login login page. You can customize the login page view by calling Webauthn::loginViewResponseUsing. See View response

    The default behavior will open the webauthn::authenticate page. You can also change the value of webauthn.views.authenticate in the configuration file.

  2. Or: Get the publicKey challenge by calling webauthn.auth.options (if not provided).

  3. Start the webauthn browser authentication. You can use the webauthn.js library to do this.

    Send the signed data to webauthn.auth route.

  4. The POST response will be:

    • a redirect response
    • or a json response with a callback data.

Example:

  <!-- load javascript part -->
  <script src="{!! secure_asset('vendor/webauthn/webauthn.js') !!}"></script>
...
  <!-- script part to run the sign part -->
  <script>
    var publicKey = {!! json_encode($publicKey) !!};

    var webauthn = new WebAuthn();

    webauthn.sign(
      publicKey,
      function (data) {
        axios.post("{{ route('webauthn.auth') }}", data)
          .then(function (response) {
            if (response.data.callback) { window.location.href = response.data.callback;}
          });
      }
    );
  </script>

If the authentication is successful, the server will use the webauthn.redirects.login configuration:

  • to redirect the response on a plain http call
  • or with a json response, like:
    {
        result: true,
        callback: `webauthn.redirects.login` target url,
    }

Register a new key

To register a new webauthn key, the workflow is the following:

  1. Open the webauthn.register page. You can customize the register page view by calling Webauthn::registerViewResponseUsing. See View response

    The default behavior will open the webauthn::register page. You can also change the value of webauthn.views.register in the configuration file.

  2. Or: Get the publicKey challenge by calling webauthn.store.options (if not provided).

  3. Start the webauthn browser registration. You can use the webauthn.js library to do this.

    Send the signed data to webauthn.store route. The data should contain a name field with the webauthn key name.

  4. The POST response will be:

    • a redirect response
    • or a json response with a callback data.

Example:

  <!-- load javascript part -->
  <script src="{!! secure_asset('vendor/webauthn/webauthn.js') !!}"></script>
...
  <!-- script part to run the sign part -->
  <script>
    var publicKey = {!! json_encode($publicKey) !!};

    var webauthn = new WebAuthn();

    webauthn.register(
      publicKey,
      function (data) {
        axios.post("{{ route('webauthn.store') }}", {
          ...data,
          name: "{{ $name }}",
        })
      }
    );
  </script>

If the registration is successful, the server will use the webauthn.redirects.register configuration:

  • to redirect the response on a plain http call
  • or with a json response, like:
    {
        result: json serialized webauthn key value,
        callback: `webauthn.redirects.register` target url,
    }

Routes

These routes are defined:

Request Route Description
GET /webauthn/auth webauthn.login The login page.
POST /webauthn/auth/options webauthn.auth.options Get the publicKey and challenge to initiate a WebAuthn login.
POST /webauthn/auth webauthn.auth Post data after a WebAuthn login validate.
GET /webauthn/keys/create webauthn.create The register key page.
POST /webauthn/keys/options webauthn.store.options Get the publicKeys and challenge to initiate a WebAuthn registration.
POST /webauthn/keys webauthn.store Post data after a WebAuthn register check.
DELETE /webauthn/keys/{id} webauthn.destroy Delete an existing key.
PUT /webauthn/keys/{id} webauthn.update Update key properties (name, ...).

You can customize the first part of the url by setting prefix value in the config file.

Ignore route creation

You can disable the routes creation by adding this in your AppServiceProvider:

use LaravelWebauthn\Services\Webauthn;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        Webauthn::ignoreRoutes();
    }
}

Customizing The Authentication Pipeline

The Laravel Webauthn authentication pipeline is highly inspired by the Fortify pipeline.

If you would like, you may define a custom pipeline of classes that login requests should be piped through. Each class should have an __invoke method which receives the incoming Illuminate\Http\Request instance and, like middleware, a $next variable that is invoked in order to pass the request to the next class in the pipeline.

To define your custom pipeline, you may use the Webauthn::authenticateThrough method. This method accepts a closure which should return the array of classes to pipe the login request through. Typically, this method should be called from the boot method of your App\Providers\FortifyServiceProvider class.

The example below contains the default pipeline definition that you may use as a starting point when making your own modifications:

use LaravelWebauthn\Actions\AttemptToAuthenticate;
use LaravelWebauthn\Actions\EnsureLoginIsNotThrottled;
use LaravelWebauthn\Actions\PrepareAuthenticatedSession;
use LaravelWebauthn\Services\Webauthn;
use Illuminate\Http\Request;

Webauthn::authenticateThrough(fn (Request $request) => array_filter([
    config('webauthn.limiters.login') !== null ? null : EnsureLoginIsNotThrottled::class,
    AttemptToAuthenticate::class,
    PrepareAuthenticatedSession::class,
]));

Rate Limiter

By default, Laravel Webauthn will throttle logins to five requests per minute for every email and IP address combination. You may specify a custom rate limiter with other specifications.

First define a custom rate limiter. Follow Laravel rate limiter documentation to create a new RateLimiter within the boot method of your application's App\Providers\AppServiceProvider class.

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    protected function boot(): void
    {
        RateLimiter::for('webauthn-login', function (Request $request) {
            return Limit::perMinute(1000);
        });
    }
}

Then use this new custom rate limiter in your webauthn.limiters.login configuration:

'limiters' => [
    'login' => 'webauthn-login',
],

Events

Events are dispatched by LaravelWebauthn:

  • \LaravelWebauthn\Events\WebauthnLogin on login with Webauthn check.
  • \LaravelWebauthn\Events\WebauthnLoginData on preparing authentication data challenge.
  • \Illuminate\Auth\Events\Failed on a failed login check.
  • \LaravelWebauthn\Events\WebauthnRegister on registering a new key.
  • \LaravelWebauthn\Events\WebauthnRegisterData on preparing register data challenge.
  • \LaravelWebauthn\Events\WebauthnRegisterFailed on failing registering a new key.

View response

You can easily change the view responses with the Webauthn service.

For instance, call Webauthn::loginViewResponseUsing in your App\Providers\AppServiceProvider class:

use LaravelWebauthn\Services\Webauthn;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        Webauthn::loginViewResponseUsing(LoginViewResponse::class);
    }
}

With a LoginViewResponse class:

use LaravelWebauthn\Http\Responses\LoginViewResponse as LoginViewResponseBase;

class LoginViewResponse extends LoginViewResponseBase
{
    public function toResponse($request)
    {
        return Inertia::render('Webauthn/WebauthnLogin', [
            'publicKey' => $this->publicKey
        ])->toResponse($request);
    }
}

List of methods and their expected response contracts:

Webauthn static methods \LaravelWebauthn\Contracts
loginViewResponseUsing LoginViewResponseContract
loginSuccessResponseUsing LoginSuccessResponseContract
registerViewResponseUsing RegisterViewResponseContract
registerSuccessResponseUsing RegisterSuccessResponseContract
destroyViewResponseUsing DestroyResponseContract
updateViewResponseUsing UpdateResponseContract

Compatibility

Laravel compatibility

This package has the following Laravel compatibility:

Laravel asbiin/laravel-webauthn
5.8-8.x <= 1.2.0
7.x-8.x 2.0.1
>= 9.x >= 3.0.0

Browser compatibility

Most of the browsers support Webauthn.

However, your browser will refuse to negotiate a relay to your security device without the following:

  • a proper domain (localhost and 127.0.0.1 will be rejected by webauthn.js)
  • an SSL/TLS certificate trusted by your browser (self-signed is okay)
  • connected HTTPS on port 443 (ports other than 443 will be rejected)

Homestead

If you are a Laravel Homestead user, the default is to forward ports. You can switch from NAT/port forwarding to a private network with similar Homestead.yaml options:

sites:
  - map: homestead.test
networks:
  - type: "private_network"
    ip: "192.168.254.2"

Re-provisioning vagrant will inform your virtual machine of the new network and install self-signed SSL/TLS certificates automatically: vagrant reload --provision

If you haven't done so already, describe your site domain and network in your hosts file:

192.168.254.2 homestead.test

License

Author: Alexis Saettler

Copyright ยฉ 2019โ€“2024.

Licensed under the MIT License. View license.

laravel-webauthn's People

Contributors

aethyn avatar asbiin avatar bistory avatar cyb0rk avatar dependabot-preview[bot] avatar dependabot[bot] avatar developstorm avatar iv-craig avatar krsriq avatar lbausch avatar markivanowich avatar matthieutirelli avatar matthijs avatar niels2080 avatar peterheider avatar willbrowningme avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

laravel-webauthn's Issues

Laravel 7 Support

The current constraint in composer.json doesn't allow Laravel 7 even though in the README it says:

This package supports Laravel 5.8 and newer, and has been tested with php 7.2 and newer versions.

This is a direct copy of #157 @asbiin can we make this more automatic or at least limit what is said in the Readme so that we aren't expecting it to work in newer versions?

Cannot read properties of undefined (reading 'create') at WebAuthn.register

Hey,
Maybe I'm doing something wrong. I have a Laravel 9 Backend and a nuxt.js frontend.
in nuxt.js I include backendurl/vendor/webauthn/webauthn.js in Scripts and this get loaded in header.
I want to register existing user for Login with webauthn, so on logged in Dashboard in Nuxt.js I request publicKey from Laravel and set this.webauthn = new WebAuthn(); (in vue.js)
in the register() Function I do

this.webauthn.register(
        this.options.publicKey,
        function (data) {
          axios.post("/web/webauthn/keys", {
            ...data,
            name: "Name",
          })
            .then()
            .catch(function (error) {
              console.log(error);
            });
        }
      );

And getting error:

TypeError: Cannot read properties of undefined (reading 'create')
    at WebAuthn.register (webauthn.js:39:25)
    at VueComponent.registrieren (WebauthnRegister.vue?72c2:20:1)
    at click (WebauthnRegister.vue?2a27:16:1)
    at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1863:1)
    at HTMLButtonElement.invoker (vue.runtime.esm.js?2b0e:2188:1)
    at original._wrapper (vue.runtime.esm.js?2b0e:6961:1)

Am I doing something wrong?

Authentication Exception thrown when calling any of the provided routes

When the user is not yet authenticated calling any of the webauthn routes (ex: register) throws an authentication exception. I've manually authenticated the user with Auth::login() to get the webauthn routes to work correctly but this completely negates the usage of webauthn.

Perhaps I am missing something, the examples are unclear. Any help you can provide is appreciated.

Fresh install - error on php artisan migrate - 1170 BLOB/TEXT column 'credentialId' used in key specification without a key length

OS: Linux Ubuntu 22.04
Laravel version: 10.1.5
MySQL version: 8.0

laravel@1f8e2eb5a18b:/var/www/html$ php artisan migrate 
Xdebug: [Step Debug] Could not connect to debugging client. Tried: localhost:9003 (fallback through xdebug.client_host/xdebug.client_port).

   INFO  Preparing database.  

  Creating migration table ............................................................................................................... 47ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ................................................................................................... 84ms DONE
  2014_10_12_100000_create_password_reset_tokens_table .................................................................................. 123ms DONE
  2019_03_29_163611_add_webauthn ........................................................................................................ 164ms FAIL

   Illuminate\Database\QueryException 

  SQLSTATE[42000]: Syntax error or access violation: 1170 BLOB/TEXT column 'credentialId' used in key specification without a key length (Connection: mysql, SQL: alter table `webauthn_keys` add index `webauthn_keys_credentialid_index`(`credentialId`))

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:760
    756โ–•         // If an exception occurs when attempting to run a query, we'll format the error
    757โ–•         // message to include the bindings with SQL, which will make this exception a
    758โ–•         // lot more helpful to the developer instead of just the database's errors.
    759โ–•         catch (Exception $e) {
  โžœ 760โ–•             throw new QueryException(
    761โ–•                 $this->getName(), $query, $this->prepareBindings($bindings), $e
    762โ–•             );
    763โ–•         }
    764โ–•     }

      +9 vendor frames 

  10  database/migrations/2019_03_29_163611_add_webauthn.php:16
      Illuminate\Support\Facades\Facade::__callStatic()
      +25 vendor frames 

  36  artisan:35
      Illuminate\Foundation\Console\Kernel::handle()

Register a new key problem

I have this message when I try to add a new key but this key is not inserted into the device yet.
Everything works when the key is already in the device. But I must get some behavior where the user must be able to access the key record before this key is inserted!

You need to log in before adding a new Webauthn authentication

Support multiple guards

In my use case I have 3 different kinds of users each with their own guard
Would it be possible to support this?

Compatibility of this package

What is the compatibility of this module? It seems that mobile browsers are not eligible for the webauthn protocol ...

'the user agent does not support public key credentials'
or
Your browser dosen't currently support webauthn ( chrome for android ).

Is there a way to configure a package, or increase the configuration of laravel to extend compatibility with chrome for android in particular?

android browser is supposed to accept this technology (canIuse )

clientDataJSON base64 padding

webauthn no longer accepts padding in clientDataJSON
this sould be corrected in resources/js/webauthn.js at WebAuthn.prototype._bufferEncode

a quick temp fix
on project/resources/views/vendor/webauthn/authenticate.blade.php
add

            data.response.clientDataJSON = data.response.clientDataJSON.replace('=', '');

to the webauthn.sign callback

web-auth/webauthn-framework#285

The relying party ID is not a registrable domain suffix of, nor equal to the current domain

Hello,

more of a questions than of a bug, I suppose. But as a webauthn beginner I cannot figure out where it comes from or how to solve it.

I am getting the error "The relying party ID is not a registrable domain suffix of, nor equal to the current domain." despite having exposed my Laravel App via Beyondcode Expose to a domain like https://mw...eq.sharedwithexpose.com/ - I have also adjusted the APP_URL, ASSET_URL and vite config. But I cannot figure out where to check or set the RP ID in this implementation.

Can you help please?

Getting "Error during the validation of the key". how do i debug this?

I have implemented the solution using jquery. I have followed the test app that is provided with the readme.

here's my code:

window.webauthn = new WebAuthn((name, message) => {
           console.log({name, message});
});

$("#add-webauth").click(function(){
        $.post(route('webauthn.store.options'), {}).done(({publicKey}) =>  {
            console.log("publicKey", publicKey);
            window.webauthn.register(
                publicKey,
                (data) => {
                    const payload = {
                        ...data,
                        name:`${device.brand} ${os.name} on ${client.name}`,
                    };
                                console.log("DATA", {payload});
                    $.post(route('webauthn.store'), payload).done(resp =>    console.log("STORE", {resp}));
                }
            );
        });
    });
{"message":"The given data was invalid.","errors":{"email":["Error during the validation of the key"]}}

Please help!

Invalid Base 64 Url Safe character

This issue is only present for versions of Webauthn newer than v4.0.5.

Description of the issue

When trying to login with a key, the following exception is thrown:

[2022-08-31 08:03:31] local.ERROR: Invalid Base 64 Url Safe character. {"userId":"498f0da2-76a2-436e-913e-231f963ef32a","exception":"[object] (Assert\\InvalidArgumentException(code: 17): Invalid Base 64 Url Safe character. at /path/to/project/vendor/beberlei/assert/lib/Assert/Assertion.php:2728)
[stacktrace]
#0 /path/to/project/vendor/beberlei/assert/lib/Assert/Assertion.php(779): Assert\\Assertion::createException()
#1 /path/to/project/vendor/web-auth/webauthn-lib/src/Util/Base64.php(16): Assert\\Assertion::regex()
#2 /path/to/project/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(132): Webauthn\\Util\\Base64::decodeUrlSafe()
#3 /path/to/project/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(77): Webauthn\\PublicKeyCredentialLoader->createResponse()
#4 /path/to/project/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAssertionValidator.php(54): Webauthn\\PublicKeyCredentialLoader->loadArray()
#5 /path/to/project/vendor/asbiin/laravel-webauthn/src/Services/Webauthn.php(135): LaravelWebauthn\\Services\\Webauthn\\CredentialAssertionValidator->__invoke()
#6 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): LaravelWebauthn\\Services\\Webauthn::validateAssertion()
#7 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(92): Illuminate\\Support\\Facades\\Facade::__callStatic()
#8 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(56): LaravelWebauthn\\Actions\\AttemptToAuthenticate->attemptValidateAssertion()
#9 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\AttemptToAuthenticate->handle()
#10 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/EnsureLoginIsNotThrottled.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#11 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\EnsureLoginIsNotThrottled->handle()
#12 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#13 /path/to/project/vendor/asbiin/laravel-webauthn/src/Http/Controllers/AuthenticateController.php(65): Illuminate\\Pipeline\\Pipeline->then()
#14 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): LaravelWebauthn\\Http\\Controllers\\AuthenticateController->store()
#15 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction()
#16 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(261): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#17 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(204): Illuminate\\Routing\\Route->runController()
#18 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\\Routing\\Route->run()
#19 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#20 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#21 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#22 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#23 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#24 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#25 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\AuthenticateSession->handle()
#26 /path/to/project/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#27 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#28 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#30 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle()
#31 /path/to/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#33 /path/to/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#35 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(726): Illuminate\\Pipeline\\Pipeline->then()
#37 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(703): Illuminate\\Routing\\Router->runRouteWithinStack()
#38 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\\Routing\\Router->runRoute()
#39 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(656): Illuminate\\Routing\\Router->dispatchToRoute()
#40 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch()
#41 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#42 /path/to/project/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle()
#44 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#45 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#46 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#47 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#48 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#49 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#50 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#51 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#52 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#53 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#54 /path/to/project/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#55 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle()
#56 /path/to/project/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#57 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#58 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#59 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then()
#60 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#61 /path/to/project/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#62 {main}
"}

Steps to reproduce:

  1. Clone the https://github.com/asbiin/laravel-webauthn-example repo
  2. Install dependencies (you may need to update vite to v0.6.0 to get it to work)
  3. Register a new key
  4. You will be able to login successfully since the composer.lock file currently has v4.0.5
  5. Run composer update, this will update Webauthn to v4.1.2 (latest version currently)
  6. Logout and try to log back in with the same key
  7. You will see the above exception

The issue is still present even if you add a new key after running composer update.

It seems quite a few files were changed in Webauthn from v4.0.5 to v4.1.2. As far as I can see the authenticatorData returned from webauthn.js has characters not considered base64 URL safe by Webauthn. So I'm not sure if an update is required there.

For the time being I've had to keep Webauthn at v4.0.5 so that my users are still able to login.

Disable logging

Is it possible to disable the the log?
I tried adding this to my AppServiceProvider, but it did not affect.

        $this->app->get(AttestationObjectLoader::class)->setLogger(new NullLogger());
        $this->app->get(AuthenticatorAttestationResponseValidator::class)->setLogger(new NullLogger());
        $this->app->get(AuthenticatorAssertionResponseValidator::class)->setLogger(new NullLogger());
        $this->app->get(PublicKeyCredentialLoader::class)->setLogger(new NullLogger());

500 Error with web-auth/webauthn-lib 4.5.0

I'm seeing a 500 error with the PublicKeyCredentialLoader class binding when registering or authenticating with version 4.5.0 of the web-auth/webauthn-lib package installed. Specifying "web-auth/webauthn-lib": "< 4.5.0", everything works as expected. This is with version 3.2.4 of asbiin/laravel-webauthn.

local.ERROR: Webauthn\PublicKeyCredentialLoader::__construct(): Argument #1 ($attestationObjectLoader) must be of type Webauthn\AttestationStatement\AttestationObjectLoader, null given, called in /app/vendor/asbiin/laravel-webauthn/src/WebauthnServiceProvider.php on line 243 {"userId":1,"exception":"[object] (TypeError(code: 0): Webauthn\\PublicKeyCredentialLoader::__construct(): Argument #1 ($attestationObjectLoader) must be of type Webauthn\\AttestationStatement\\AttestationObjectLoader, null given, called in /app/vendor/asbiin/laravel-webauthn/src/WebauthnServiceProvider.php on line 243 at /app/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php:36)
[stacktrace]
#0 /app/vendor/asbiin/laravel-webauthn/src/WebauthnServiceProvider.php(243): Webauthn\\PublicKeyCredentialLoader->__construct()
#1 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(889): LaravelWebauthn\\WebauthnServiceProvider->LaravelWebauthn\\{closure}()
#2 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(774): Illuminate\\Container\\Container->build()
#3 /app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(860): Illuminate\\Container\\Container->resolve()
#4 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(710): Illuminate\\Foundation\\Application->resolve()
#5 /app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(845): Illuminate\\Container\\Container->make()
#6 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(1047): Illuminate\\Foundation\\Application->make()
#7 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(963): Illuminate\\Container\\Container->resolveClass()
#8 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(924): Illuminate\\Container\\Container->resolveDependencies()
#9 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(774): Illuminate\\Container\\Container->build()
#10 /app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(860): Illuminate\\Container\\Container->resolve()
#11 /app/vendor/laravel/framework/src/Illuminate/Container/Container.php(710): Illuminate\\Foundation\\Application->resolve()
#12 /app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(845): Illuminate\\Container\\Container->make()
#13 /app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(120): Illuminate\\Foundation\\Application->make()
#14 /app/vendor/asbiin/laravel-webauthn/src/Services/Webauthn.php(142): app()
#15 /app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): LaravelWebauthn\\Services\\Webauthn::validateAssertion()
#16 /app/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(92): Illuminate\\Support\\Facades\\Facade::__callStatic()
#17 /app/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(56): LaravelWebauthn\\Actions\\AttemptToAuthenticate->attemptValidateAssertion()
#18 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\AttemptToAuthenticate->handle()
#19 /app/vendor/asbiin/laravel-webauthn/src/Actions/EnsureLoginIsNotThrottled.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#20 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\EnsureLoginIsNotThrottled->handle()
#21 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#22 /app/vendor/asbiin/laravel-webauthn/src/Http/Controllers/AuthenticateController.php(65): Illuminate\\Pipeline\\Pipeline->then()
#23 /app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): LaravelWebauthn\\Http\\Controllers\\AuthenticateController->store()
#24 /app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#25 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#26 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#27 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\\Routing\\Route->run()
#28 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#29 /app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#30 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#31 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#33 /app/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#35 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#37 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle()
#38 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#40 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#42 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(799): Illuminate\\Pipeline\\Pipeline->then()
#44 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): Illuminate\\Routing\\Router->runRouteWithinStack()
#45 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(740): Illuminate\\Routing\\Router->runRoute()
#46 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(729): Illuminate\\Routing\\Router->dispatchToRoute()
#47 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\\Routing\\Router->dispatch()
#48 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#49 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#50 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#51 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#52 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#53 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#54 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#55 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#56 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#57 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#58 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#59 /app/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#60 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle()
#61 /app/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#62 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#63 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#64 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\\Pipeline\\Pipeline->then()
#65 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(134): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#66 /app/public/index.php(59): Illuminate\\Foundation\\Http\\Kernel->handle()
#67 {main}

Please let me know if there's any additional information I can provide!

Inconsistant field type used

the default users table has a data type of bigIncrements and the webauthn table references this as an unsignedInteger and results in an error

SQLSTATE[HY000]: General error: 1005 Can't create table `main`.`webauthn_keys` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `webauthn_keys` add constraint `webauthn_keys_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)

As outlined here

https://stackoverflow.com/questions/40863517/laravel-errno-150-foreign-key-constraint-is-incorrectly-formed

challenge and id tokens are Base64Url not Base64

Uncaught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
at WebAuthn._bufferDecode (/vendor/webauthn/webauthn.js:133:18)
at WebAuthn.sign (/vendor/webauthn/webauthn.js:77:40)
at HTMLDocument. (/webauthn/auth:192:12)
at mightThrow (eval at /js/app.js:72:1), :3578:29)
at process (eval at (/js/app.js:72:1), :3646:12)

Server-side. if I modify

PublicKeyCredentialRequestOptions.php:167
[-] 'challenge' => Base64Url::encode($this->challenge),
[+] 'challenge' => base64_encode($this->challenge),

and

PublicKeyCredentialDescriptor.php:104
[-] 'id' => Base64Url::encode($this->id),
[+] 'id' => base64_encode($this->id),

window.atob completes successfully, and I can authenticate.

Alternately, client-side, if I add a function to pre-decode from Base64Url to Base64 before calling window.atob, then I can authenticate successfully:

webauth.js:133
[-] var t = window.atob(value);
[+] var t = window.atob(this.preDecodeBase64Url(value));

And helper function:

WebAuthn.prototype.preDecodeBase64Url = function (input) {

// Replace non-url compatible chars with base64 standard chars
input = input
    .replace(/-/g, '+')
    .replace(/_/g, '/');

// Pad out with standard base64 required padding characters
var pad = input.length % 4;
if(pad) {
    if(pad === 1) {
        throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding');
    }
    input += new Array(5-pad).join('=');
}

return input;

}

separate authentication and registration route guard

i have this problem where the authentication routes don't need auth guard, but the config key for auth middleware is set to both routes. i use sanctum as the auth guard, so the authentication routes are inaccessible as it throws Target class [sanctum] does not exist. as the server response.

currently, both routes have the config key webauthn.guard for its middleware, with the registration having it on its auth middleware. it would be convenient for api creation if both routes can have their own guard configuration.

these are the code lines in question:

config('webauthn.guard', 'web'),

config('webauthn.auth_middleware', 'auth').':'.config('webauthn.guard', 'web'),

i haven't found other solutions than to edit the vendor files directly, as i am quite a beginner at this

many thanks in any case

Support for Laravel 8 as an API?

So, currently I have 1 running Laravel (v8) app.
Is this latest version still support for Laravel 8? or any other version can I use for Laravel 8?

If not, Is that possible to use this as an API?
I tried to build the sample app (it worked) but I have no idea how to integrate with my Laravel 8 app.
Thank you!

Key Specification without a key length

php artisan migrate

INFO Running migrations.

2019_03_29_163611_add_webauthn ................................... 36ms FAIL

Illuminate\Database\QueryException

SQLSTATE[42000]: Syntax error or access violation: 1170 BLOB/TEXT column 'credentialId' used in key specification without a key length (Connection: mysql, SQL: alter table webauthn_keys add index webauthn_keys_credentialid_index(credentialId))

at vendor/laravel/framework/src/Illuminate/Database/Connection.php:793
789โ–• // If an exception occurs when attempting to run a query, we'll format the error
790โ–• // message to include the bindings with SQL, which will make this exception a
791โ–• // lot more helpful to the developer instead of just the database's errors.
792โ–• catch (Exception $e) {
โžœ 793โ–• throw new QueryException(
794โ–• $this->getName(), $query, $this->prepareBindings($bindings), $e
795โ–• );
796โ–• }
797โ–• }

  +9 vendor frames

10 database/migrations/2019_03_29_163611_add_webauthn.php:16
Illuminate\Support\Facades\Facade::__callStatic("create")

  +24 vendor frames

35 artisan:35
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

not configurable RP ID

i get this error on my front end domain:

SecurityError: The RP ID "<api-host-domain>" is invalid for this domain
    at identifyRegistrationError (index.js:125:20)
    at startRegistration (index.js:204:15)

since my laravel is hosted on a different subdomain

can this have another config field like 'rp_id' => env('FRONTEND_URL') ? parse_url(env('FRONTEND_URL'), PHP_URL_HOST) : null, ?

or is there a better way around this

many thanks

Registering a webauthn key (touch id and passkey tried) fails when using @simplewebauthn/browser

Hi,

We are using @simplewebauthn/browser in our project to register webauthn keys and to login to our service. But when using this project it fails to register the key with the following error:

[2024-02-02 15:08:34] local.INFO: Trying to load data from an array {"data":{"id":"<cut>","rawId":"<cut>","response":{"attestationObject":"<random characters>","clientDataJSON":"<more random characters>","transports":["internal"],"publicKeyAlgorithm":-7,"publicKey":"<public key>","authenticatorData":"<more characters>"},"type":"public-key"}}
[2024-02-02 15:08:34] local.INFO: Trying to load the data {"data":"<more characters>"}
[2024-02-02 15:08:34] local.INFO: Loading the Attestation Statement
[2024-02-02 15:08:34] local.INFO: Attestation Statement loaded
[2024-02-02 15:08:34] local.DEBUG: Attestation Statement loaded {"attestationStatement":{"Webauthn\\AttestationStatement\\AttestationStatement":{"fmt":"none","attStmt":[],"trustPath":{"type":"Webauthn\\TrustPath\\EmptyTrustPath"},"type":"none"}}}
[2024-02-02 15:08:34] local.INFO: Attestation Object loaded
[2024-02-02 15:08:34] local.DEBUG: Attestation Object {"ed":{"Webauthn\\AttestationStatement\\AttestationObject":{"metadataStatement":null,"rawAttestationObject":"<more characters>","attStmt":{"fmt":"none","attStmt":[],"trustPath":{"type":"Webauthn\\TrustPath\\EmptyTrustPath"},"type":"none"},"authData":{"authData":"<cut>๏ฟฝH๏ฟฝny๏ฟฝ๏ฟฝ@๏ฟฝ๏ฟฝ\u0011\u0011o~๏ฟฝI\u0000\u0010>๏ฟฝ๏ฟฝ)1๏ฟฝF\"๏ฟฝ๏ฟฝj6h6๏ฟฝ๏ฟฝ\u0001\u0002\u0003& \u0001!X 4<cut>","rpIdHash":"<cut>a~๏ฟฝy๏ฟฝ\u0018v\u0013๏ฟฝ๏ฟฝ๏ฟฝ_n</cut>","flags":"E","signCount":0,"attestedCredentialData":{"aaguid":"<uuid>","credentialId":"<characters>","credentialPublicKey":"<public key>"},"extensions":null}}}}
[2024-02-02 15:08:34] local.INFO: The data has been loaded
[2024-02-02 15:08:34] local.DEBUG: Public Key Credential {"publicKeyCredential":{"Webauthn\\PublicKeyCredential":"{\"type\":\"public-key\",\"id\":\"<some id>\",\"transports\":[\"internal\"]}"}}
[2024-02-02 15:08:34] local.DEBUG: Webauthn publicKey deserialize error {"exception":"[object] (JsonException(code: 4): Syntax error at /projecten/frontend/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAttestationValidator.php:51)
[stacktrace]
#0 /projecten/frontend/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAttestationValidator.php(51): json_decode('', true, 512, 4194304)
#1 /projecten/frontend/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAttestationValidator.php(40): LaravelWebauthn\\Services\\Webauthn\\CredentialAttestationValidator->pullPublicKey(Object(App\\Models\\User))
#2 /projecten/frontend/vendor/asbiin/laravel-webauthn/src/Services/Webauthn.php(143): LaravelWebauthn\\Services\\Webauthn\\CredentialAttestationValidator->__invoke(Object(App\\Models\\User), Array)
#3 /projecten/frontend/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(355): LaravelWebauthn\\Services\\Webauthn::validateAttestation(Object(App\\Models\\User), Array, 'bla')

Hopefully this gives a pointer on where to search whats going on.

The post to the register/options succeeds and I get a publicKey object with the required info. But the register fails with the error as stated above.

Uncaught TypeError: e is undefined

After figuring out how to integrate it, with the example application, I am now facing the following problem:

Uncaught TypeError: e is undefined

The affected code is this here:

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t:"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WebAuthn=t:e.WebAuthn=t}(this, WebAuthn);

especially this: e.WebAuthn

Depending on my google search, this is a jQuery function, that means this package needs jQuery?

passwordless login

I am trying to make passwordless login from this example.
I can't seem to doAutheniticate, it says "{"error":{"message":"The credential ID is invalid."}}"
How to implement passwordless with this example, please?

Could not set attachment to platform

Hi, I am using 2.0.1 with Laravel 8, currently, I am trying to test it with the default webauthn/auth view. the problem is that i could not use platform regardless of what I have set in the config file, and the PublicKeyCredentialRequestOptions never add this option either. how do i use it with face id?.

thanks

Webauthn\AuthenticatorSelectionCriteria::createFromArray(): Argument #1 ($json) must be of type array, Webauthn\AuthenticatorSelectionCriteria given

Hi there,

I am using your demo application as a guide to get webauthn working inside my project but I've run into a bit of an issue when adding a key. Please let me know if you need additional information, I'd be more than happy to provide.

A snippet of the error is below alongside the full error on pastebin due to its length.

Versions:
laravel-webauthn - 4.1.1
laravel - 10.22.0
@simplewebauthn/browser - 8.0.2
PHP 8.2.10 (using Valet)

[2023-09-25 00:35:22] local.INFO: The data has been loaded  
[2023-09-25 00:35:22] local.DEBUG: Public Key Credential {"publicKeyCredential":{"Webauthn\\PublicKeyCredential":"{\"type\":\"public-key\",\"id\":\"NyRMIrAWYpN_2_gdDq8QhxgzAjamKI4MYW6ulpSznrA\",\"transports\":[\"internal\"]}"}} 
[2023-09-25 00:35:22] local.ERROR: Webauthn\AuthenticatorSelectionCriteria::createFromArray(): Argument #1 ($json) must be of type array, Webauthn\AuthenticatorSelectionCriteria given, called in /Users/lewislarsen/sites/tabship/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php on line 275 {"userId":"2d55b8ba-4688-4351-8826-5402f513ad8e","exception":"[object] (TypeError(code: 0): Webauthn\\AuthenticatorSelectionCriteria::createFromArray(): Argument #1 ($json) must be of type array, Webauthn\\AuthenticatorSelectionCriteria given, called in /Users/lewislarsen/sites/tabship/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php on line 275 at /Users/lewislarsen/sites/tabship/vendor/web-auth/webauthn-lib/src/AuthenticatorSelectionCriteria.php:180)
[stacktrace]
#0 /Users/lewislarsen/sites/tabship/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php(275): Webauthn\\AuthenticatorSelectionCriteria::createFromArray(Object(Webauthn\\AuthenticatorSelectionCriteria))

Full log: https://pastebin.com/Q8LUjbSA

Thank you!

2FA can be avoided

Hello !
I seem to have found a vulnerability in laravel-webauthn.

I used https://laravel-webauthn-example.herokuapp.com/ and my website to test, and can replicate this behaviour.

When I create an account, I set a 2FA key by going to /register route.
Then I logout, and when I log back in, I get redirected to /webauthn/auth.

At this point, if i manually go to /webauthn/register, i can register a new 2FA to the system, and login with that new token i added.

Expected behaviour would be to reject me adding a new 2FA to an account if I did not first verify myself to be the account owner.

Wrong defined constructors and binds

Hi, I am sorry but I am either dumb or this package cannot work the way it is.

Example 1:

I am trying to save key and call webauthn.store

ERROR: Webauthn\AuthenticatorAttestationResponseValidator::__construct(): Argument #2 ($publicKeyCredentialSource) must be of type Webauthn\PublicKeyCredentialSourceRepository, null given, called in vendor/asbiin/laravel-webauthn/src/WebauthnServiceProvider.php on line 188

$this->app->bind(
            AuthenticatorAttestationResponseValidator::class,
            fn ($app) => tap(new AuthenticatorAttestationResponseValidator(
                $app[AttestationStatementSupportManager::class],
                null,
                null,
                $app[ExtensionOutputCheckerHandler::class]
            ), function ($responseValidator) use ($app) {
                $responseValidator->setLogger($app['webauthn.log']);
            })
        );

but declaration for AuthenticatorAttestationResponseValidator does not accept null values.

public function __construct(
        private readonly AttestationStatementSupportManager $attestationStatementSupportManager,
        private readonly PublicKeyCredentialSourceRepository $publicKeyCredentialSource,
        private readonly TokenBindingHandler $tokenBindingHandler,
        private readonly ExtensionOutputCheckerHandler $extensionOutputCheckerHandler
    ) {

Example 2:

I can come this far only if I fix example 1
ERROR: Webauthn\AuthenticatorAttestationResponseValidator::check(): Argument #3 ($request) must be of type Psr\Http\Message\ServerRequestInterface, string given, called in vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAttestationValidator.php on line 38

// Services/Webauthn/CredentialAttestationValidator.php:38
return $this->validator->check(
            $this->getResponse($publicKeyCredential),
            $this->pullPublicKey($user),
            $this->request->host() // this is string
        );

but method check expects SserverRequestInterface

public function check(
        AuthenticatorAttestationResponse $authenticatorAttestationResponse,
        PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions,
        ServerRequestInterface $request,
        array $securedRelyingPartyId = []
    ): PublicKeyCredentialSource

and many others... when I had to extend and overwrite lot of files I started to doubt my sanity and said to myself that I am doing something wrong because there is no way this package have so many bugs.

Dynamic model used instead of forcing to use User

Any possibility to dynamically change default auth model from User to another model since Laravel support dynamic auth model?
e.g :
In my case, I am using Staffs (not Users) table which has staff_id (not user_id) as the primary key.

Modify routes

Is there a way to modify the routes? I found where they are generated: \LaravelWebauthn\WebauthnServiceProvider::registerRoutes() but that is in the vendor directory and I don't want to modify them there.

I want to add the password.confirm middleware to the webauthn.destroy route.

Apple TouchID support

Hi.
I have a user in one of my websites that are not able to use his iPhone's TouchID feature for webAuthn authencation.
Is there a possibility to have it added? Or if support already exists, am i missing something?
Thanks

Laravel 7.6 compatibility?

My composer.json contains these lines
"asbiin/laravel-webauthn": "^0.7.0",
"laravel/framework": "^7.6",

$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Conclusion: don't install laravel/framework v7.6.1
- Conclusion: don't install laravel/framework v7.6.0
- Conclusion: don't install laravel/framework v7.5.2
- Conclusion: don't install laravel/framework v7.5.1
- Conclusion: don't install laravel/framework v7.5.0
- Conclusion: don't install laravel/framework v7.4.0
- Conclusion: don't install laravel/framework v7.3.0
- Conclusion: don't install laravel/framework v7.2.2
- Conclusion: don't install laravel/framework v7.2.1
- Conclusion: don't install laravel/framework v7.2.0
- Conclusion: don't install laravel/framework v7.1.3
- Conclusion: don't install laravel/framework v7.1.2
- Conclusion: don't install laravel/framework v7.1.1
- Conclusion: don't install laravel/framework v7.1.0
- Conclusion: don't install laravel/framework v7.0.8
- Conclusion: don't install laravel/framework v7.0.7
- Conclusion: don't install laravel/framework v7.0.6
- Conclusion: don't install laravel/framework v7.0.5
- Conclusion: don't install laravel/framework v7.0.4
- Conclusion: don't install laravel/framework v7.0.3
- Conclusion: don't install laravel/framework v7.0.2
- Installation request for asbiin/laravel-webauthn ^0.7.0 -> satisfiable by asbiin/laravel-webauthn[0.7.0].
- Conclusion: don't install laravel/framework v7.0.1
- Conclusion: don't install laravel/framework v7.0.0
- asbiin/laravel-webauthn 0.7.0 requires laravel/framework ^5.8 || ^6.0 -> satisfiable by laravel/framework[5.8.x-dev, 6.x-dev].
- Can only install one of: laravel/framework[7.x-dev, 5.8.x-dev].
- Can only install one of: laravel/framework[7.x-dev, 6.x-dev].
- Installation request for laravel/framework ^7.0 -> satisfiable by laravel/framework[7.x-dev, v7.0.0, v7.0.1, v7.0.2, v7.0.3, v7.0.4, v7.0.5, v7.0.6, v7.0.7, v7.0.8, v7.1.0, v7.1.1, v7.1.2, v7.1.3, v7.2.0, v7.2.1, v7.2.2, v7.3.0, v7.4.0, v7.5.0, v7.5.1, v7.5.2, v7.6.0, v7.6.1].

Array cache driver does not work

This is less of an issue, more of a warning
If you have set your cache driver to array
you will not be able to register or validate a key, as the package keeps this data in a cache and must persist between requests.

Maybe you can add a notice in the readme to save others form debugging this issue.

Thank you.

Can't change view response to Inertia

I tried to copy the example from the readme but I get the following exception:

Symfony\Component\HttpFoundation\Response::setContent(): Argument #1 ($content) must be of type ?string, Inertia\Response given, called in /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Response.php on line 72

README:

You can easily change the view responses with the Webauthn service.
For instance, call Webauthn::loginViewResponseUsing in your AppServiceProvider:

use LaravelWebauthn\Services\Webauthn;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        Webauthn::loginViewResponseUsing(LoginViewResponse::class);
    }
}

With a LoginViewResponse class:

use LaravelWebauthn\Http\Responses\LoginViewResponse as LoginViewResponseBase;

class LoginViewResponse extends LoginViewResponseBase
{
    public function toResponse($request)
    {
        $publicKey = $this->publicKeyRequest($request);

        return Inertia::render('Webauthn/WebauthnLogin', [
            'publicKey' => $publicKey
        ]);
    }
}

I guess right now it's just working with blade views? Also, $this->publicKeyRequest does not exist, though that's not the cause for this problem.

axios integrity wrong

cannot login because axios is not loaded to register and authenticate views
axios is set to dev url
should be changed to a production url

    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js"
            integrity="sha512-odNmoc1XJy5x1TMVMdC7EMs3IVdItLPlCeL5vSUPN2llYKMJ2eByTTAIiiuqLg+GdNr9hF6z81p27DArRFKT7A=="
            crossorigin="anonymous" referrerpolicy="no-referrer"></script>

some yubikeys are erroring out in Chrome

I am having an issue with some Yubikeys on asbiin/laravel-webauthn:^3.3.1 and web-auth/webauthn-lib:^4.6.0 for Chromium browsers -- Firefox works just fine. I have other (older and newer) keys that work on Chrome from Yubikey.

Error happens when trying to create the credentials:

DOMException: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.

Keys that don't work:
5C NFC (firmware 5.2.7)
Yubikey 2 (firmware 5.2.4)

My current workaround: using "web-auth/webauthn-lib": "~4.5.2" in composer.

Invalid Base 64 Url Safe character

Description of the issue

Unable to register new webauthn key (tested with chrome emulation and yubikey) because of exception.

Environment

Exception stacktrace

[2022-09-09 14:20:40] local.ERROR: Webauthn error: LaravelWebauthn\Events\WebauthnRegisterFailed {"exception":"[object] (Assert\\InvalidArgumentException(code: 17): Invalid Base 64 Url Safe character. at /var/www/html/vendor/beberlei/assert/lib/Assert/Assertion.php:2728)
[stacktrace]
#0 /var/www/html/vendor/beberlei/assert/lib/Assert/Assertion.php(779): Assert\\Assertion::createException()
#1 /var/www/html/vendor/web-auth/webauthn-lib/src/Util/Base64.php(16): Assert\\Assertion::regex()
#2 /var/www/html/vendor/web-auth/webauthn-lib/src/CollectedClientData.php(64): Webauthn\\Util\\Base64::decodeUrlSafe()
#3 /var/www/html/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(128): Webauthn\\CollectedClientData::createFormJson()
#4 /var/www/html/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(77): Webauthn\\PublicKeyCredentialLoader->createResponse()
#5 /var/www/html/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAttestationValidator.php(55): Webauthn\\PublicKeyCredentialLoader->loadArray()
#6 /var/www/html/vendor/asbiin/laravel-webauthn/src/Services/Webauthn.php(168): LaravelWebauthn\\Services\\Webauthn\\CredentialAttestationValidator->__invoke()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): LaravelWebauthn\\Services\\Webauthn::validateAttestation()
#8 /var/www/html/vendor/asbiin/laravel-webauthn/src/Actions/ValidateKeyCreation.php(45): Illuminate\\Support\\Facades\\Facade::__callStatic()
#9 /var/www/html/vendor/asbiin/laravel-webauthn/src/Actions/ValidateKeyCreation.php(28): LaravelWebauthn\\Actions\\ValidateKeyCreation->validateAttestation()
#10 /var/www/html/vendor/asbiin/laravel-webauthn/src/Http/Controllers/WebauthnKeyController.php(45): LaravelWebauthn\\Actions\\ValidateKeyCreation->__invoke()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): LaravelWebauthn\\Http\\Controllers\\WebauthnKeyController->store()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(261): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(204): Illuminate\\Routing\\Route->runController()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\\Routing\\Route->run()
#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#17 /var/www/html/vendor/vincentbean/laravel-plausible/src/Middleware/TrackPlausiblePageviews.php(17): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): VincentBean\\LaravelPlausible\\Middleware\\TrackPlausiblePageviews->handle()
#19 /var/www/html/vendor/inertiajs/inertia-laravel/src/Middleware.php(92): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Inertia\\Middleware->handle()
#21 /var/www/html/vendor/laravel/jetstream/src/Http/Middleware/ShareInertiaData.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Jetstream\\Http\\Middleware\\ShareInertiaData->handle()
#23 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\AuthenticateSession->handle()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Auth\\Middleware\\Authenticate->handle()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#33 /var/www/html/app/Http/Middleware/SentryContext.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\SentryContext->handle()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(726): Illuminate\\Pipeline\\Pipeline->then()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(703): Illuminate\\Routing\\Router->runRouteWithinStack()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\\Routing\\Router->runRoute()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(656): Illuminate\\Routing\\Router->dispatchToRoute()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#49 /var/www/html/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#53 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#55 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#61 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(38): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Fruitcake\\Cors\\HandleCors->handle()
#63 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#65 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#66 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then()
#67 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#68 /var/www/html/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#69 /var/www/html/server.php(21): require_once('...')
#70 {main}
"} 

Demo application stopped working

https://webauthn.asbin.net

there was some change and the buttons now point to non https links, therefore this error message

Mixed Content: The page at 'https://webauthn.asbin.net/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://webauthn.asbin.net/register'. This request has been blocked; the content must be served over HTTPS.

Issue with POST request to webauthn.store.options

Discussed in #454

Originally posted by hcuadra811 September 28, 2023
I am following the instructions to register using the package for my REST API. I did the following:

  • Added route middleware to Kernel.php
  • Set up the driver in the providers array in config/auth.php
  • Disabled views in config/webauthn.php

Then I sent a POST request to /webauthn/keys/options in order to get the public key. But I'm getting a CSRF token mismatch error. In the read me I am not seeing anything regarding CSRF tokens. How can I fix this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.