laragear / poke
保持表单活动状态,通过温和地“戳”Laravel应用避免TokenMismatchException
Requires
- php: ^8.1
- illuminate/http: 10.*|11.*
- illuminate/routing: 10.*|11.*
- illuminate/support: 10.*|11.*
- illuminate/view: 10.*|11.*
- laragear/meta: 3.*
Requires (Dev)
- laragear/meta-testing: 2.*
- orchestra/testbench: 8.*|9.*
README
保持表单活动状态,通过温和地“戳”Laravel应用避免 TokenMismatchException
。
成为赞助商
您的支持使我能够保持此包免费、更新和可维护。或者,您也可以 传播这个词!
要求
- Laravel 10 或更高版本。
安装
使用Composer将此包引入您的项目
composer require laragear/poke
它是如何工作的?
此包通过给定间隔向指定的 /poke
路由发送HTTP HEAD
请求来“戳”您的应用。作为回报,在您的应用程序更新会话时长时,它返回一个HTTP 204
状态码,这是一个没有主体的OK响应。
这仅仅相当于 仅0.8 KB的数据传输!
在CSRF令牌过期时自动重新加载
Poke脚本将检测CSRF会话令牌是否已过期,基于最后成功的戳击,并在有互联网连接的情况下强制重新加载页面。
这是通过检测 浏览器或标签页变为活动状态时,或 设备用户再次在线时 来实现的。
这在用户笔记本电脑休眠或手机失去信号的情况下非常有用。因为这些时刻会话可能会过期,所以在浏览器唤醒或手机在线时,页面会重新加载以获取新的CSRF令牌。
用法
有三种方法可以在您的应用中启用Poke。
auto
(易于管理的默认模式)中间件
blade
(最佳性能)
您可以使用环境文件更改默认模式
POKE_MODE=auto
auto
只需安装此包,然后 看看它如何运行。这将向 “web”组 添加一个中间件,该中间件将检查所有响应的内容,其中
- 请求接受HTML,并且
- 存在带有
csrf
令牌的输入。
如果有任何匹配项,这将在</body>
标签之前注入负责保持表单活动状态的Poke脚本。
此模式不会在错误响应或重定向中注入脚本。
注意
如果您的应用程序有大量路由或包含大量文本的响应,建议使用其他模式。
中间件
此模式不会将中间件推送到“web”组。相反,它允许您只在您决定的路线中使用poke
中间件。
use Illuminate\Support\Facades\Route; use App\Http\Controllers\Auth\RegisterController; Route::get('register', RegisterController::class)->middleware('poke');
如果存在带有CSRF令牌的输入,这将向路由响应中注入脚本。您还可以将其应用于 路由组。
您可能想使用force
选项强制在<body>
标签的末尾注入脚本,无论CSRF令牌输入是否存在。当您期望在视图加载后动态加载表单或SPA时,这可能会很有用。
use Illuminate\Support\Facades\Route; use App\Http\Controllers\StatusController; Route::get('status', StatusController::class)->middleware('poke:force');
与auto
模式一样,此模式在发生错误或重定向时不会注入脚本。
blade
blade
模式禁用了中间件注入,因此您可以自由地使用<x-poke-script />
组件在视图中任何地方注入脚本,最好在</body>
标签关闭之前。
<body> <h2>Try to Login:</h2> <form action="/login" method="post"> @csrf <input type="text" name="username" required> <input type="password" name="password" required> <button type="submit">Log me in!</button> </form> <x-poke-script /> <!-- This is a good place to put it --> </body>
如果您有大量响应,如博客文章、文章或图库,这可能很有用,因为框架不会花费资源检查响应,而只是渲染组件。
提示
如果您的视图中存在重复的Poke组件,请不要担心。脚本只渲染一次,即使不是这样,脚本也只运行一次。
配置
为了精细调整,您可以发布poke.php
配置文件。
php artisan vendor:publish --provider="Laragear\Poke\PokeServiceProvider" --tag="config"
让我们看看配置数组
return [ 'mode' => env('POKE_MODE', 'auto'), 'times' => 4, 'poking' => [ 'route' => 'poke', 'name' => 'poke', 'domain' => null, 'middleware' => 'web', ] ];
次数(间隔)
相对于全局会话生命周期的探测次数。次数越多,探测间隔越短。默认的4
对于任何正常应用程序都应该足够。
例如,如果我们的会话生命周期是默认的120分钟
- 则每40分钟探测应用3次,
- 每30分钟探测应用4次,
- 每24分钟探测应用5次,
- 每20分钟探测应用6次,依此类推...
换句话说,会话生命周期 / 次数 = 探测间隔
。
- 🔺 如果您预计用户在您的网站上闲置几分钟,甚至几个小时,请提高间隔。
- 🔻 如果您预计用户活动频繁,请降低间隔。
探测
这是接收Poke脚本请求的探测路由的设置数组。
return [ 'poking' => [ 'route' => 'poke', 'name' => 'poke', 'domain' => null, 'middleware' => ['web'], ] ];
路由
用于接收探测的路由(相对于应用程序的根URL)。
return [ 'poking' => [ 'route' => '/dont-sleep' ], ];
注意
探测路由在启动时注册。
名称
路由的名称,以便在需要时在应用程序中找到探测路由。
return [ 'poking' => [ 'name' => 'my-custom-poking-route' ], ];
域名
探测路由在所有域名上可用。设置特定域名将使路由局限于该域名。
如果您正在使用域名或域名模式,将探测路由放在某个域名下可能更方便。一个经典的例子是将探测设置为在http://user.myapp.com/poke
可用,但不在http://api.myapp.com/poke
。
return [ 'poking' => [ 'domain' => '{user}.myapp.com' ], ];
中间件
默认的Poke路由使用web
中间件组来正常工作,因为这个组处理会话、cookie和CSRF令牌。
如果您需要,可以在此处添加自己的中间件。
return [ 'poking' => [ 'middleware' => ['web', 'validates-ip', 'my-custom-middleware'] ], ];
您也可以使用“最小化”中间件,如果您觉得合适,如果您不知道自己在做什么,这可能会成为问题。
return [ 'poking' => [ 'middleware' => [ \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\VerifyCsrfToken::class, ], ] ]
脚本视图
Poke始终将脚本注入为Blade组件。
您可以通过在views
标签下发布它来覆盖脚本。
php artisan vendor:publish --provider="Laragear\Poke\PokeServiceProvider" --tag="views"
有些人可能想更改脚本以使用自定义的JavaScript HTTP库、压缩响应、使其与旧浏览器兼容,或者甚至在CSRF令牌过期时创建自定义事件。
视图接收三个变量
$route
:探测将执行的相对路由。$interval
:执行探测的时间间隔(以毫秒为单位)。$lifetime
:会话生命周期(以毫秒为单位)。
Laravel Octane 兼容性
- 仅将
InjectsScript
中间件绑定为一个单例,并保存模式,该模式将在整个进程生命周期内持续存在。该模式不打算按请求逐个更改。
使用此包与 Laravel Octane 一起使用应该没有问题。
安全性
如果您发现任何与安全相关的问题,请通过电子邮件darkghosthunter@gmail.com联系,而不是使用问题跟踪器。
许可证
本特定包版本根据发布时的MIT 许可证条款进行许可。
Laravel是Taylor Otwell的商标。版权所有 © 2011-2024 Laravel LLC。