Я новичок в Laravel и изо всех сил пытаюсь реализовать простую политику :)
Просто для тестирования я сделал ->
/app/Policies/ReleasePolicy.php:
<?php
namespace App\Policies;
use App\Models\Release;
use App\Models\User;
use Illuminate\Auth\Access\Response;
class ReleasePolicy
{
public function edit(): bool
{
return false;
}
}
маршруты/web.php:
<?php
use App\Models\Release;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ReleaseController;
Route::resource('/release', ReleaseController::class);
приложение/http/controllers/ReleaseController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Release;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
use Illuminate\View\View;
use App\Http\Requests\ReleaseStoreRequest;
use App\Http\Requests\ReleaseUpdateRequest;
class ReleaseController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(Release $release): View
{
return view('pages.release.edit', compact('release'));
}
}
Когда я захожу на http://localhost:8000/release/56/edit, он все равно открывается, я ожидал 403. Что я делаю не так?
Я предполагаю, что политика не зарегистрирована/обнаружена, но почему бы и нет? В laravel/docs говорится:
По умолчанию Laravel автоматически обнаруживает политики, если модель и политика соответствуют стандартным соглашениям об именах Laravel. В частности, политики должны находиться в каталоге Policies, расположенном в каталоге, содержащем ваши модели, или выше него.
И я именно так и сделал, но думаю, политика до сих пор не обнаружена...
Я попытался вручную зарегистрировать политику в app/Providers/AppServiceProvider.php.
<?php
namespace App\Providers;
use App\Models\Release;
use App\Policies\ReleasePolicy;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Models\User;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::policy(Release::class, ReleasePolicy::class);
}
}
Ничего не изменилось. http://localhost:8000/release/56/edit не показывает 403
Политики защищают не методы контроллера, а действия над моделями. В документации https://laravel.com/docs/11.x/authorization#policy-methods мы видим, что есть некоторые методы, которые Laravel автоматически обнаруживает:
viewAny, просмотр, создание, обновление, удаление, восстановление и принудительное удаление
В вашем случае вам нужно будет явно проверить наличие политики в методе редактирования, как описано в документации: https://laravel.com/docs/11.x/authorization#authorizing-or-throwing-Exceptions
public function edit(Release $release): View
{
Gate::authorize('edit', $release);
return view('pages.release.edit', compact('release'));
}
Или я предлагаю вам использовать стандартный метод политики «обновления» вместо специального «редактирования»:
class ReleasePolicy
{
/**
* Determine if the given release can be updated by the user.
*/
public function update(User $user, Release $release): bool
{
return false;
//or some rule...;
}
}
И используйте «обновление» в контроллере: Gate::authorize('update', $release);