Laravel策略不适用于路由中间件



我有一个NotificationPolicy,代码如下:

<?php
namespace AppPolicies;
use AppNotification;
use AppUser;
use IlluminateAuthAccessHandlesAuthorization;
class NotificationPolicy
{
    use HandlesAuthorization;
    public function update(User $user, Notification $notification)
    {
        return $user->id === $notification->user_id;
    }
}

我已通过将其添加到AuthServiceProvider:中来正确注册

protected $policies = [
    Notification::class => NotificationPolicy::class,
];

我这样做是为了只有登录的用户才能通过将archived_at值或read_at值设置为当前时间戳来更新他们的通知。如果我在控制器中使用该策略,则该策略确实有效,即。;

class ArchiveItemController extends Controller
{
    public function __invoke(Notification $notification)
    {
        $this->authorize('update', $notification);
        $notification->markAsArchived();
        return redirect()->route('inbox.index')->with('success', 'Item has been archived');
    }
}

但是,我不想在控制器中使用它们,更喜欢在我的路由文件中使用它们。所以我已经从控制器中删除了这条线路$this->authorize('update', $notification);,我尝试了以下操作,但它不起作用:

Route::prefix('inbox')->middleware(['auth', 'can:employee'])->group(function () {
    Route::get('/notification/{notification}/archive', 'UserAccountInboxArchiveItemController')
       ->name('inbox.item.archive')
       ->middleware('can:update', 'notification');
});

我甚至运行了以下内容,但它们没有什么区别:

php artisan optimize
php artisan cache:clear
php artisan route:cache
php artisan view:clear
php artisan config:cache

您的中间件声明不正确。

您必须将'can:update', 'notification'更改为'can:update,notification'才能工作:

所以最终你会得到以下内容:

Route::prefix('inbox')->middleware(['auth', 'can:employee'])->group(function () {
    Route::get('/notification/{notification}/archive', 'UserAccountInboxArchiveItemController')
        ->name('inbox.item.archive')
        ->middleware('can:update,notification');
});

如果已缓存路由,则必须运行php artisan route:clear才能使更改生效。

来自文档:

Laravel包含一个中间件,可以在传入的请求甚至到达您的路由或控制器。默认情况下,CCD_ 9中间件被分配AppHttpKernel类中的can键。让我们来看看使用can中间件授权用户可以更新博客帖子:

use AppPost;
Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');

在本例中,我们将向can中间件传递两个参数。这个第一个是我们希望授权的行动的名称,第二个是我们希望传递给策略方法的路由参数。在这个在这种情况下,由于我们使用隐式模型绑定,Post模型将传递给策略方法。如果用户未被授权执行给定的操作,具有403状态代码的HTTP响应将是由中间件生成。

最新更新