Skip to content

锁定属性

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 将继续默认使公共属性可自由修改,并为开发者提供根据需要锁定它们的工具。