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

Laravel Policy not working on route middleware

我有一个 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->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

您的中间件声明不正确。

您必须将 '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 includes a middleware that can authorize actions before the incoming request even reaches your routes or controllers. By default, the Illuminate\Auth\Middleware\Authorize middleware is assigned the can key in your App\Http\Kernel class. Let's explore an example of using the can middleware to authorize that a user can update a blog post:

use App\Post;

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

In this example, we're passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method. In this case, since we are using implicit model binding, a Post model will be passed to the policy method. If the user is not authorized to perform the given action, a HTTP response with a 403 status code will be generated by the middleware.