Laravel 政策不适用于 update/delete 型号 运行

Laravel policy not running on update/delete model

我正在努力使这项政策发挥作用,并且我已遵循文档。但似乎政策代码甚至不是 运行.

我有 Role 型号。我创建了 RolePolicy。我想在策略中做的事情是确保 ID 为 1 的角色永远不会被更新或删除。

我的 RolePolicy 看起来像这样:

<?php

namespace App\Policies;

use App\Models\Role;
use Illuminate\Support\Facades\Response;

class RolePolicy
{
    /**
     * Determine whether the user can update the model.
     *
     * @param  \App\User  $user
     * @param  \App\Models\Role  $role
     * @return mixed
     */
    public function update(Role $role)
    {
        return $role->id === 1
        ? Response::deny('Cannot change super-admin role')
        : Response::allow();
    }

    /**
     * Determine whether the user can delete the model.
     *
     * @param  \App\User  $user
     * @param  \App\Models\Role  $role
     * @return mixed
     */
    public function delete(Role $role)
    {
        return $role->id === 1
        ? Response::deny('Cannot delete super-admin role')
        : Response::allow();
    }
}

我什至尝试在策略的删除和更新方法中执行 dd(),但是当我尝试 delete/update ID 为 1 的模型时,没有任何反应。 dd 不会 运行,上面当前代码中的响应也不会。

我已经在 AuthServiceProvider 中注册了政策,我也有这个门来授予超级管理员所有权限。

<?php

namespace App\Providers;

use App\Models\Role;
use App\Policies\RolePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Role::class => RolePolicy::class
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        // Implicitly grant "Super Admin" role all permissions
        // This works in the app by using gate-related functions like auth()->user->can() and @can()
        Gate::before(function($user, $ability) {
            return $user->hasRole('super-admin') ? true : null;
        });
    }
}

这也是我更新Role模型的RoleController方法:

/**
 * Edit role
 *
 * @param Edit $request
 * @param Role $role
 * @return void
 */
public function postEdit(Edit $request, Role $role)
{
    # Validation checks happens in the FormRequest
    # Session flash also happens in FormRequest

    # Update model
    $role->update([
        'name' => $request->name
    ]);

    # Sync permissions
    $permissions = Permission::whereIn('name', $request->input('permissions', []))->get();
    $role->syncPermissions($permissions);

    return redirect(route('dashboard.roles.edit.get', ['role' => $role->id]))->with('success', 'Changes saved');
}

我用来授予所有权限的 gate 与不是 运行ning 的策略有什么关系吗?或者我在这里做错了什么?

如果有人能指出正确的方向,请提前致谢。

您的 Laravel 应用程序中包含的 User 模型包括两种有用的授权操作方法:cancantcan 方法接收您希望授权的操作和相关模型。例如,让我们确定用户是否有权更新给定的 Role 模型:

if ($user->can('update', $role)) {
    //
}

如果为给定模型注册了策略,can 方法将自动调用适当的策略和 return 布尔结果。如果没有为模型注册策略,can 方法将尝试调用与给定操作名称匹配的基于闭包的门。

通过控制器助手

除了为 User 模型提供的有用方法外,Laravel 还为任何扩展 App\Http\Controllers\Controller 基础 class。与 can 方法一样,此方法接受您希望授权的操作名称和相关模型。如果该操作未经授权,authorize 方法将抛出一个 Illuminate\Auth\Access\AuthorizationException,默认的 Laravel 异常处理程序会将其转换为具有 403 状态代码的 HTTP 响应:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Role;
use Illuminate\Http\Request;

class RoleController extends Controller
{
    /**
     * Update the given role.
     *
     * @param  Request  $request
     * @param  role  $role
     * @return Response
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function update(Request $request, Role $role)
    {
        $this->authorize('update', $role);

        // The current user can update the role...
    }
}

AuthServiceProvider 中的 Gate::before 方法是问题所在。删除了它并重写了权限、策略和一些门以从策略中获取错误消息。

决定授予角色 super-admin 权限 * 并使用 $user->can() 和中间件 .....->middlware('can:*') 进行检查,现在一切正常。