【发布时间】:2020-02-12 09:07:46
【问题描述】:
我在一份申请中全职工作了 2 年。我经常遇到这个错误,比方说每隔几个月,但从来没有设法以可靠的方式修复它,因为它只是消失了,我永远找不到“为什么”。
所以,又来了,我不知道为什么以及如何解决它。这一次,我正在写一些东西,所以下次我会有一个收藏页面。
这是错误:
如果我对策略方法进行任何更改,例如在 app/Policies/UserPolicy 中,则在刀片中使用 @can 或在 php 文件中使用 $user->can 时不会考虑更改。我可以在策略中引入die,在函数的最开始引入Log::debug('something') 甚至return false,但不,仍然返回true。
这是一个代码示例:
文件:app/Policies/UserPolicy
public function deleteUser(User $user, User $target)
{
return false;
if ($user->id === $target->id) {
return false;
}
// [...]
}
这是代码测试,它返回 true,无论我在策略代码中做什么:
$me = Auth::user();
dd($me->can('deleteUser', $me));
本来这个例子应该返回false,但它返回true,我不知道为什么。修改代码并没有改变任何事情,就像有一个没有什么可以清除的缓存。我已经尝试了所有我知道的缓存清除命令:
- php artisan 缓存:清除
- php 工匠配置:清除
- php工匠视图:清除
- php artisan clear-compiled
- 作曲家转储自动加载
甚至重新启动 apache,等等...我检查了 php.ini,我没有启用 OPCache(行注释,但我也尝试使用 OPcache.enabled=0,没有更改)。
也许原因在别处,但我不知道去哪里找。正如我所说,这个错误通常会自行消失,而我没有时间找到原因。
重现错误的其他方式
在刀片中,如果我写:
@can('deleteUser', $user)
CAN
@endcan
它总是显示 CAN。例如,如果我将策略文件中的函数重命名为 deleteUserr,则没有任何变化(仍然返回 true)。但是,如果我将刀片代码更改为@can('deleteUserr', $user),那么我不会显示“CAN”,因为找不到此函数并且未找到规则的结果总是错误的。
环境
WSL(Ubuntu 18.04、apache 2.4.29、php 7.2.19)、Laravel 6.0.3
感谢您的帮助!
编辑/解决:找到罪魁祸首!
与作曲家包spatie/laravel-permission的交互不好。
我有一个名为“deleteUser”的 spatie 权限并被授予。包可能重载了“->can”方法,现在在继续策略路由之前首先检查其权限机制。所以我的 UserPolicy@deleteUser 被简单地忽略了。
【问题讨论】:
-
你在用
spatie/laravel-permission包吗? -
您是否在策略上定义了
Gate::before或Gate::after过滤器或before? -
@Styx 是的。我还将命令
php artisan cache:forget 'spatie.permission.cache'添加到我的缓存清除 bash @lagbox 我看不到您在说什么,所以我想您的问题的答案是“否” -
你试过
artisan permission:cache-reset吗? -
@Styx 我很确定我找到了问题所在。我有一个名为“deleteUser”的权限(来自 spatie 包)。显然,发生了一些变化,并且此检查比策略功能更早进行。所以无论策略逻辑是什么,如果授予 spatie 权限,它就是真的,就是这样。