asbiin / laravel-webauthn
Laravel Webauthn 支持
Requires
- php: >=8.1
- illuminate/support: ^9.0 || ^10.0 || ^11.0
- phpdocumentor/reflection-docblock: ^5.3
- psr/http-factory-implementation: 1.0
- symfony/property-access: ^6.4 || ^7.0
- symfony/property-info: ^6.4 || ^7.0
- symfony/serializer: ^6.4 || ^7.0
- web-auth/cose-lib: ^4.0
- web-auth/webauthn-lib: ^4.8
- web-token/jwt-library: ^3.0
Requires (Dev)
- ext-sqlite3: *
- guzzlehttp/psr7: ^2.1
- jschaedl/composer-git-hooks: ^4.0
- larastan/larastan: ^2.0
- laravel/legacy-factories: ^1.0
- laravel/pint: ^1.13
- ocramius/package-versions: ^2.0
- orchestra/testbench: ^7.0 || ^8.0 || ^9.0
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpstan/phpstan-strict-rules: ^1.0
- phpunit/phpunit: ^9.5 || ^10.0 || ^11.0
- psalm/plugin-laravel: ^2.8
Suggests
- guzzlehttp/psr7: To provide a psr/http-factory-implementation implementation
- php-http/discovery: To find a psr/http-factory-implementation implementation
- psr/http-client-implementation: Required for the AndroidSafetyNet Attestation Statement support
- symfony/psr-http-message-bridge: To find a psr/http-factory-implementation implementation
Conflicts
- web-auth/webauthn-lib: 4.7.0
- dev-main
- 4.6.0
- 4.5.0
- 4.4.1
- 4.4.0
- 4.3.0
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.5.0
- 3.4.0
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.1
- 3.0.0
- 3.0.0-beta.4
- 3.0.0-beta.3
- 3.0.0-beta.2
- 3.0.0-beta.1
- 2.0.1
- 2.0.0
- 1.2.0
- 1.1.0
- 1.0.0
- 0.9.1
- 0.9.0
- 0.8.0
- 0.7.0
- 0.6.4
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
- dev-dependabot/github_actions/SonarSource/sonarcloud-github-action-3
This package is auto-updated.
Last update: 2024-08-26 11:31:04 UTC
README
LaravelWebauthn 是用于在 Laravel 中使用 Webauthn 作为2FA(双因素认证)或无密码认证的适配器。
现在在演示应用程序上试用。
功能
- 管理 Webauthn 密钥注册
- 第二因素认证:添加中间件服务以使用 Webauthn 密钥作为 2FA
- 使用 Webauthn 密钥登录,无需密码
安装
使用以下命令安装此包:
composer require asbiin/laravel-webauthn
配置
您可以将 LaravelWebauthn 配置发布到名为 config/webauthn.php
的文件中,并使用 vendor:publish
命令发布资源
php artisan vendor:publish --provider="LaravelWebauthn\WebauthnServiceProvider"
接下来,您应该迁移您的数据库
php artisan migrate
设置
选项1:添加 LaravelWebauthn 中间件
Webauthn 中间件将强制用户对某些路由进行 Webauthn 密钥认证。
将中间件分配给路由或路由组
use LaravelWebauthn\Http\Middleware\WebauthnMiddleware; Route::get('/home', function () { // ... })->middleware(WebauthnMiddleware::class);
当需要时,Webauthn 中间件将用户重定向到 Webauthn 登录页面。
通过记住密码登录
当会话过期,但用户设置了 remember
cookie 时,您可以通过订阅 LaravelWebauthn\Listeners\LoginViaRemember
监听器来重新验证 Webauthn 会话
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 ); } }
选项2:无密码认证
您可以使用 Webauthn 通过仅使用 Webauthn 密钥认证来认证用户,而无需密码。
要启用无密码认证,首先添加 Webauthn 用户提供者:更新您的 config/auth.php
文件并更改 users
提供者
'providers' => [ 'users' => [ 'driver' => 'webauthn', 'model' => App\Models\User::class, ], ],
然后允许您的登录页面通过 email
标识符启动 Webauthn 登录。
您可以通过向 webauthn.auth.options
路由发送 POST 请求并带有 email
输入来获取挑战数据。有关更多详细信息,请参阅认证部分。
禁用视图
默认情况下,LaravelWebauthn 定义了用于返回认证和注册密钥视图的路由。
但是,如果您正在构建由 JavaScript 驱动的单页应用程序,则可能不需要这些路由。因此,您可以通过将应用程序的 config/webauthn.php
配置文件中的 views
配置值设置为 false 完全禁用这些路由。
'views' => false,
缓存
请注意,此包使用缓存在服务器请求和浏览器响应之间存储挑战数据。您需要从您的 config/cache.php
文件设置真实的缓存驱动程序,因此您不能使用 array
或 null
驱动程序。
用法
您可以在 asbiin/laravel-webauthn-example 中找到用法示例。您现在可以在演示应用程序上尝试它。
认证
使用 Webauthn 密钥进行认证的工作流程如下
-
打开
webauthn.login
登录页面。您可以通过调用Webauthn::loginViewResponseUsing
来自定义登录页面视图。请参阅 查看响应默认行为将打开 webauthn::authenticate 页面。您还可以在配置文件中更改
webauthn.views.authenticate
的值。 -
或者:通过调用
webauthn.auth.options
获取公钥挑战(如果未提供)。 -
启动 webauthn 浏览器身份验证。您可以使用
webauthn.js
库来完成此操作。将签名数据发送到
webauthn.auth
路由。 -
POST 响应将是
- 重定向响应
- 或包含
callback
数据的 json 响应。
示例
<!-- 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>
如果身份验证成功,服务器将使用 webauthn.redirects.login
配置
- 在纯 http 调用中重定向响应
- 或使用如下 json 响应,例如
{ result: true, callback: `webauthn.redirects.login` target url, }
注册新密钥
要注册新的 webauthn 密钥,工作流程如下
-
打开
webauthn.register
页面。您可以通过调用Webauthn::registerViewResponseUsing
来自定义注册页面视图。请参阅 查看响应默认行为将打开 webauthn::register 页面。您还可以在配置文件中更改
webauthn.views.register
的值。 -
或者:通过调用
webauthn.store.options
获取公钥挑战(如果未提供)。 -
启动 webauthn 浏览器注册。您可以使用
webauthn.js
库来完成此操作。将签名数据发送到
webauthn.store
路由。数据应包含一个name
字段,其中包含 webauthn 密钥名称。 -
POST 响应将是
- 重定向响应
- 或包含
callback
数据的 json 响应。
示例
<!-- 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>
如果注册成功,服务器将使用 webauthn.redirects.register
配置
- 在纯 http 调用中重定向响应
- 或使用如下 json 响应,例如
{ result: json serialized webauthn key value, callback: `webauthn.redirects.register` target url, }
路由
这些路由已定义
您可以通过在配置文件中设置 prefix
值来自定义 URL 的第一部分。
忽略路由创建
您可以通过在 AppServiceProvider
中添加以下内容来禁用路由创建
use LaravelWebauthn\Services\Webauthn; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ public function register(): void { Webauthn::ignoreRoutes(); } }
自定义认证管道
Laravel Webauthn 身份验证管道高度受 Fortify 管道 启发。
如果您愿意,可以定义一个自定义的类管道,登录请求应通过该管道。每个类都应该有一个 __invoke
方法,该方法接收传入的 Illuminate\Http\Request
实例,并像中间件一样有一个 $next
变量,用于调用以将请求传递给管道中的下一个类。
要定义您自己的自定义管道,您可以使用 Webauthn::authenticateThrough
方法。此方法接受一个闭包,该闭包应返回要管道化登录请求的类数组。通常,此方法应在您的 App\Providers\FortifyServiceProvider
类的 boot
方法中调用。
以下示例包含默认管道定义,您可以在进行自己的修改时将其用作起点
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, ]));
速率限制器
默认情况下,Laravel Webauthn 将每分钟为每个电子邮件和 IP 地址组合限制登录为五个请求。您可以使用其他指定来指定自定义速率限制器。
首先定义一个自定义速率限制器。按照 Laravel 速率限制器文档,在您的应用程序的 App\Providers\AppServiceProvider
类的 boot
方法中创建一个新的 RateLimiter。
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); }); } }
然后在此 webauthn.limiters.login
配置中使用此新的自定义速率限制器
'limiters' => [ 'login' => 'webauthn-login', ],
事件
事件由 LaravelWebauthn 分发
\LaravelWebauthn\Events\WebauthnLogin
在使用 Webauthn 进行登录检查时。\LaravelWebauthn\Events\WebauthnLoginData
在准备身份验证数据挑战时。\Illuminate\Auth\Events\Failed
在登录检查失败时。\LaravelWebauthn\Events\WebauthnRegister
在注册新密钥时。\LaravelWebauthn\Events\WebauthnRegisterData
在准备注册数据挑战时。\LaravelWebauthn\Events\WebauthnRegisterFailed
在注册新密钥失败时。
视图响应
您可以使用 Webauthn 服务轻松更改视图响应。
例如,在您的 App\Providers\AppServiceProvider
类中调用 Webauthn::loginViewResponseUsing
。
use LaravelWebauthn\Services\Webauthn; class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ public function register(): void { Webauthn::loginViewResponseUsing(LoginViewResponse::class); } }
使用一个 LoginViewResponse
类。
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); } }
方法列表及其预期的响应合约。
兼容性
Laravel 兼容性
此包具有以下 Laravel 兼容性。
浏览器兼容性
大多数浏览器 支持 Webauthn。
但是,没有以下内容,您的浏览器将拒绝与您的安全设备协商中继:
- 一个适当的域名(localhost 和 127.0.0.1 将被
webauthn.js
拒绝) - 您的浏览器信任的 SSL/TLS 证书(自签名证书是可以的)
- 443 端口的 HTTPS 连接(除了 443 以外的端口将被拒绝)
Homestead
如果您是 Laravel Homestead 用户,默认情况下是转发端口。您可以使用与 Homestead.yaml
类似的选项从 NAT/端口转发切换到私有网络。
sites: - map: homestead.test networks: - type: "private_network" ip: "192.168.254.2"
重新配置 Vagrant 将通知您的虚拟机新的网络并自动安装自签名的 SSL/TLS 证书:vagrant reload --provision
如果您还没有这样做,请描述您的站点域名和网络在您的 hosts 文件中。
192.168.254.2 homestead.test
许可证
作者: Alexis Saettler
版权 © 2019–2024。
许可协议:MIT 协议。 查看许可。