为啥我的 Laravel 策略总是返回 false?

Posted

技术标签:

【中文标题】为啥我的 Laravel 策略总是返回 false?【英文标题】:Why does my Laravel policy always return false?为什么我的 Laravel 策略总是返回 false? 【发布时间】:2021-05-15 13:42:10 【问题描述】:

政策代码在这里:

class userOwnedClassPolicy

    use HandlesAuthorization;
    ...
    public function create(User $user)
    
        return ($user->userType == 'teacher');
    
    ...

因此,此政策已在 AuthServiceProvider.php 文件中注册:

class AuthServiceProvider extends ServiceProvider

    //Map models to authorization policies.
    protected $policies = [
        App\Models\classMember::class => App\Policies\classMemberPolicy::class,
        App\Models\evaluation::class => App\Policies\evaluationPolicy::class,
        App\Models\group::class => App\Policies\groupPolicy::class,
        App\Models\groupMember::class => App\Policies\groupMemberPolicy::class,
        App\Models\sharedClass::class => App\Policies\sharedClassPolicy::class,
        App\Models\slg::class => App\Policies\slgPolicy::class,
        App\Models\spreadsheet::class => App\Policies\spreadsheetPolicy::class,
        App\Models\spreadsheetValue::class => App\Policies\spreadsheetValuePolicy::class,
        App\Models\teacher::class => App\Policies\teacherPolicy::class,
        App\Models\test::class => App\Policies\testPolicy::class,
        App\Models\userOwnedClass::class => App\Policies\userOwnedClassPolicy::class
    ];

    public function boot()
    
        $this->registerPolicies();
    

(我也尝试使用文件路径的字符串来注册策略,但这没有任何作用。)

控制器代码的相关部分在这里:

class ClassController extends Controller

    ...
    public function store(Request $postReq)
    
        $this->authorize('create', Auth::user());
        userOwnedClass::create([
            'name' => $postReq->input('className'),
            'ownerId' => Auth::user()->id
        ]);
    
    ...

我尝试用return true 替换策略的create 方法中的代码,但即使这样也失败了。我做错了什么,为什么控制器在调用时总是返回 403 错误?

【问题讨论】:

试试$this->authorize('create', userOwnedClass::class); 这行得通,但你能解释一下为什么吗?为什么我在策略中不使用userOwnedClass 类时需要传递它,为什么不需要传递我在策略中使用的Auth::user() 对象? 授权系统需要知道您正在检查授权的对象(资源)的类型,这就是它如何知道何时使用策略,通过参数类型或传递的类名跨度> 那么,如何将参数传递给授权方法? 正如 IGP 所说,您的策略方法不接受资源的参数,因为它没有被定义,所以它只接受类名;这样它就可以将其与政策相匹配,这是在文档laravel.com/docs/8.x/… 【参考方案1】:

当您创建策略 userOwnedClassPolicy 并将其设置为 AuthServiceProvider 中的 userOwnedClass 模型时:

App\Models\userOwnedClass::class => App\Policies\userOwnedClassPolicy::class

你不能只运行策略方法:

$this->authorize('create', Auth::user());

当您运行上面的这一行时,您告诉 - 检查 create 方法以获取 \App\Models\User 对象的策略,但您没有为此模型创建任何策略。

所以在这种情况下你应该像这样运行它:

$this->authorize('create', \App\Models\userOwnedClass::class);

然后 Laravel 会知道它应该从 userOwnedClassPolicy 策略运行 create 方法,它会自动将当前经过身份验证的用户传递给策略方法中的 $user 变量。

【讨论】:

以上是关于为啥我的 Laravel 策略总是返回 false?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Receiver for Charge 状态总是返回 false?

Laravel 编辑策略

Laravel 4 Auth::attempt() 总是返回 false

为啥我的 ACF 自定义字段总是返回 false 或数组?

为啥我的线性搜索总是返回 false,即使该项目在数组中?

为啥 Cache::lock() 在 Laravel 7 中返回 false?