laravel - Laravel Policy 不适用于路由中间件
问题描述
我有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
以使更改生效。
从文档:
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
中间件传递了两个参数。第一个是我们希望授权的操作的名称,第二个是我们希望传递给策略方法的路由参数。在这种情况下,由于我们使用隐式模型绑定,Post
模型将被传递给策略方法。如果用户无权执行给定的操作,403
中间件将生成带有状态码的 HTTP 响应。
推荐阅读
- java - 我需要自己为 Hibernate TableGenerator 创建表吗?
- android - 如何从 rapidapi 获取基本 url 和端点以探索 json 项目
- mysql - Mysql EXISTS vs IN 性能缓慢
- mysql - 由于外键导致插入或更新错误
- flutter - SUUNTO API OAuth2第二步如何避免401 Unauthorized response?
- node.js - 正确定位源文件夹以返回所有文件路径
- javascript - 在 Safari 上替代 navigator.storage.estimate()
- python - Django - 如何将 pre_signed s3 (boto3) url 返回给客户端以供下载
- blazor - Blazor Hybrid iOS 应用程序未加载
- javascript - 从 D3.js v3 迁移到 D3.js v7 不起作用