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.
我有一个 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 thecan
key in yourApp\Http\Kernel
class. Let's explore an example of using thecan
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, aPost
model will be passed to the policy method. If the user is not authorized to perform the given action, a HTTP response with a403
status code will be generated by the middleware.