Locked
Livewire 属性可通过 wire:model 等工具在前端与后端自由修改。若要防止某个属性(例如模型 ID)在前端被修改,可以使用 Livewire 的 #[Locked] 属性。
基本用法
下面是一个 show-post 组件,将 Post 模型的 ID 存为名为 $id 的公共属性。为防止好奇或恶意用户修改该属性,可为其加上 #[Locked] 属性:
WARNING
请确保导入属性类
请确保导入所用的属性类。例如,下面的 #[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 属性不会被篡改。
TIP
模型属性默认是安全的
若将 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 将继续默认让公共属性可自由修改,并提供工具让开发者按需锁定它们。