Перейти к содержанию

Атрибут Locked⚓︎

Атрибут #[Locked] предотвращает изменение свойств на стороне клиента, защищая конфиденциальные данные, такие как идентификаторы моделей, от подмены пользователями.

Базовое использование⚓︎

Примените атрибут #[Locked] к любому публичному свойству, которое не должно изменяться с фронтенда:

resources/views/components/post/⚡show.blade.php
<?php

use Livewire\Attributes\Locked;
use Livewire\Component;
use App\Models\Post;

new class extends Component {
    #[Locked]
    public $postId;

    public function mount($id)
    {
        $this->postId = $id;
    }

    public function delete()
    {
        Post::find($this->postId)->delete();

        return redirect('/posts');
    }
};

Если пользователь попытается изменить заблокированное свойство через DevTools браузера или путем подмены запросов, Livewire выдаст исключение и предотвратит выполнение действия.

Изменения на бэкенде по-прежнему разрешены

Свойства с атрибутом #[Locked] все еще могут быть изменены в PHP-коде вашего компонента. Блокировка предотвращает только вмешательство со стороны клиента. Будьте осторожны и не передавайте непроверенные пользовательские данные в заблокированные свойства в своих собственных методах.

Когда использовать⚓︎

Используйте #[Locked], когда вам нужно:

  • Сохранять идентификаторы моделей, которые никогда не должны меняться пользователями
  • Сохранять данные, чувствительные к авторизации, на протяжении всего жизненного цикла компонента
  • Защитить любое публичное свойство, которое выступает в качестве границы безопасности

Свойства моделей защищены по умолчанию

Если вы храните модель Eloquent в публичном свойстве, Livewire автоматически гарантирует, что её ID не будет подменен — атрибут #[Locked] не требуется:

resources/views/components/post/⚡show.blade.php
<?php

use Livewire\Component;
use App\Models\Post;

new class extends Component {
    public Post $post; // Уже защищено

    public function mount($id)
    {
        $this->post = Post::find($id);
    }
};

Почему не защищенные свойства?⚓︎

Вы можете задаться вопросом, почему нельзя просто использовать protected свойства для конфиденциальных данных.

Помните, что Livewire сохраняет только публичные свойства между запросами. Защищенные свойства подходят для статических, жестко закодированных значений, но любые данные, которые необходимо сохранять во время выполнения, должны использовать публичное свойство для корректного сохранения между запросами.

Здесь #[Locked] становится незаменимым: он дает вам персистентность публичных свойств с защитой от подмены на стороне клиента.

Разве Livewire не может делать это автоматически?⚓︎

В идеальном мире Livewire блокировал бы свойства по умолчанию и разрешал изменения только тогда, когда в этом свойстве используется wire:model.

К сожалению, это потребовало бы от Livewire парсинга всех ваших шаблонов Blade, чтобы понять, изменяется ли свойство через wire:model или аналогичный API.

Это не только добавило бы технических и накладных расходов на производительность, но и сделало бы невозможным определение того, изменяется ли свойство чем-то вроде Alpine или любым другим кастомным JavaScript.

Поэтому Livewire продолжит делать публичные свойства свободно изменяемыми по умолчанию и предоставлять разработчикам инструменты для их блокировки по мере необходимости.