【问题标题】:Laravel Policy not working on route middlewareLaravel Policy 不适用于路由中间件
【发布时间】:2020-11-12 23:36:01
【问题描述】:

我有一个NotificationPolicy,代码如下:

<?php

namespace App\Policies;

use App\Notification;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;

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-&gt;authorize('update', $notification);,我尝试了以下方法,但它不起作用:

Route::prefix('inbox')->middleware(['auth', 'can:employee'])->group(function () {
    Route::get('/notification/{notification}/archive', 'User\Account\Inbox\ArchiveItemController')
       ->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

【问题讨论】:

  • 根据docs 应该是:-&gt;middleware('can:update,notification')
  • 非常感谢 Remul。我犯了一个错误,因为我有 -&gt;middleware('can:update', 'notification') 当你正确地说它应该是 -&gt;middleware('can:update,notification') - 我必须运行以下命令才能使更改生效:php artisan cache:clear &amp;&amp; php artisan config:clear &amp;&amp; php artisan route:clear &amp;&amp; php artisan view:clear &amp;&amp; php artisan clear-compiled &amp;&amp; composer dumpautoload

标签: laravel routes authorization middleware policy


【解决方案1】:

您的中间件声明不正确。

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

所以最后你会得到以下结果:

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

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

来自docs

Laravel 包含一个中间件,可以在 传入的请求甚至会到达您的路由或控制器。默认, Illuminate\Auth\Middleware\Authorize 中间件被分配了 can 键入您的 App\Http\Kernel 类。让我们探索一个例子 使用can 中间件授权用户可以更新博客 帖子:

use App\Post;

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

在本例中,我们向 can 中间件传递了两个参数。这 第一个是我们希望授权的动作的名称,第二个是 我们希望传递给策略方法的路由参数。在这个 案例,因为我们使用implicit model bindingPost 模型将是 传递给策略方法。如果用户无权执行 给定的操作,带有403 状态代码的 HTTP 响应将是 由中间件生成。

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 2017-07-04
    • 2017-08-06
    • 2016-02-02
    • 2016-02-07
    • 1970-01-01
    • 2018-12-13
    • 2015-02-05
    • 2019-04-24
    相关资源
    最近更新 更多