我有一个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响应将是由中间件生成。