主题
锁定属性
Livewire 属性可以使用 wire:model 等实用程序在前端和后端自由修改。如果你想防止属性(如模型 ID)在前端被修改,可以使用 Livewire 的 #[Locked] 属性。
基本用法
以下是一个 show-post 组件,它将 Post 模型的 ID 存储为名为 $id 的公共属性。要防止此属性被好奇或恶意用户修改,你可以将 #[Locked] 属性添加到该属性:
确保导入属性类
确保导入任何属性类。例如,下面的 #[Locked] 属性需要以下导入 use Livewire\Attributes\Locked;。
php
<?php // resources/views/components/post/⚡show.blade.php
use Livewire\Attributes\Locked;
use Livewire\Component;
new class extends Component
{
#[Locked] // [tl! highlight]
public $id;
public function mount($postId)
{
$this->id = $postId;
}
// ...
};通过添加 #[Locked] 属性,你可以确保 $id 属性永远不会被篡改。
模型属性默认是安全的
如果你在公共属性中存储 Eloquent 模型而不仅仅是模型的 ID,Livewire 将确保 ID 不会被篡改,而无需显式地向属性添加 #[Locked] 属性。在大多数情况下,这是比使用 #[Locked] 更好的方法:
php
<?php // resources/views/components/post/⚡show.blade.php
use Livewire\Component;
use App\Models\Post;
new class extends Component
{
public Post $post; // [tl! highlight]
public function mount($postId)
{
$this->post = Post::find($postId);
}
// ...
};为什么不使用 protected 属性?
你可能会问自己:为什么不对敏感数据使用 protected 属性?
请记住,Livewire 仅在网络请求之间持久化公共属性。对于静态、硬编码的数据,protected 属性是合适的。但是,对于在运行时存储的数据,你必须使用公共属性以确保数据正确持久化。
Livewire 不能自动处理吗?
在理想的世界中,Livewire 会默认锁定属性,并且仅在该属性上使用 wire:model 时才允许修改。
不幸的是,这需要 Livewire 解析你的所有 Blade 模板以了解属性是否被 wire:model 或类似的 API 修改。
这不仅会增加技术和性能开销,而且无法检测属性是否被 Alpine 或任何其他自定义 JavaScript 修改。
因此,Livewire 将继续默认使公共属性可自由修改,并为开发者提供根据需要锁定它们的工具。