我正在用 laravel 和 vue 编写一个应用程序。我已经在圣所和微风上做了认证。她工作。我想授权用户操作,以便他可以在网站上创建内容(如果他具有适当的角色)。我写了政策:
class NftPolicy
{
public function create(User $user): bool
{
// return $user->role === 'admin' || $user->role === 'author';
return true;
}
我在启动时在App Service Provider中注册了它:
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
//
}
public function boot(): void
{
Gate::policy(Nft::class, NftPolicy::class);
ResetPassword::createUrlUsing(function (object $notifiable, string $token) {
return config('app.frontend_url')."/password-reset/$token?email={$notifiable->getEmailForPasswordReset()}";
});
}
}
我尝试在控制器中使用它(不要注意其中当前的代码,我尝试了很多选项,它仍然不起作用):
class StoreNftController extends Controller
{
public function __invoke(StoreRequest $request)
{
if (Gate::denies('create', Nft::class)) {
abort(403, 'Unauthorized action.');
}
// Gate::authorize('create', Nft::class);
$data = $request->validated();
$data['author_id'] = auth()->id();
$nft = Nft::create($data);
return response()->json($nft, 201);
}
}
当我尝试执行某项操作时,总是收到 403 错误。无论我如何更改,错误仍然存在。尽管我检查了用户是否已通过身份验证,但他从服务器到达客户端,并且在服务器上,如果您尝试将他输出到 laravel.log,数据将在那里,但错误仍然存在。
我看到有人说你需要将策略放在模型的文件夹中,在旧的信息中策略是在AuthServiceProvider中注册的,但在版本11中没有这样的事情。也许我在某个地方没有完成某些事情.. 我希望得到帮助。
看起来您在 Laravel 中设置授权策略的方向是正确的。但是,您面临的问题可能与您在控制器中调用策略的方式以及定义
Gate
检查的方式有关。
您可以进行一些调整来排除故障并解决问题:
确保
NftPolicy
中的方法名称与您在控制器中检查的权限相匹配。由于您使用的是 Gate::denies('create', Nft::class)
,因此方法名称应该是 create
,您已经拥有了。但是,您需要传递 Nft
的实际实例或正确使用 Nft::class
。
Gate::denies
通话对
Gate::denies
的调用应传递模型的实例,如果您只想检查没有任何特定实例的策略,则应传递 null:
if (Gate::denies('create', Nft::class)) {
abort(403, 'Unauthorized action.');
}
Gate::authorize
您可以使用
Gate::authorize
代替,这样更简洁,并且如果授权失败会抛出异常:
Gate::authorize('create', Nft::class);
由于
create
中当前的 NftPolicy
方法始终返回 true
,因此请确保正确分配和检查用户角色。您可能想暂时更改您的策略以查看它是否被正确调用:
public function create(User $user): bool
{
\Log::info('User Role: ' . $user->role); // Log the user's role
return $user->role === 'admin' || $user->role === 'author';
}
确保您的
NftPolicy
已在 AppServiceProvider
中正确注册,并且模型 Nft
已正确定义。在 Laravel 11 中,它应该位于 App\Policies\NftPolicy
。
要进一步调试,您可以使用 Tinker 测试您的策略。运行
php artisan tinker
并尝试:
$user = App\Models\User::find(1); // Use a valid user ID
Gate::forUser($user)->allows('create', App\Models\Nft::class);
如果您需要检查
Nft
的特定实例,您可能需要调整处理实例的方式:
public function create(User $user, Nft $nft = null): bool
{
return $user->role === 'admin' || $user->role === 'author';
}
最后,仔细检查用户在访问此端点时是否确实经过身份验证。您可以通过登录并检查
auth()->user()
来完成此操作。
您的控制器应如下所示:
class StoreNftController extends Controller
{
public function __invoke(StoreRequest $request)
{
Gate::authorize('create', Nft::class);
$data = $request->validated();
$data['author_id'] = auth()->id();
$nft = Nft::create($data);
return response()->json($nft, 201);
}
}
通过这些调整,您应该能够调试并解决 403 Unauthorized 问题。让我知道进展如何!