我在策略中有一个检查用户是否可以访问页面的方法。页面名称和当前用户是策略方法的参数:
public function pageAllowed(User $user, string $page)
{
return $this->allGranted($user) || $user->hasPermission(self::PREFIX_PAGE . '.' . $page);
}
问题是我无法正常检查刀片服务器,如果我这样做
@can('page-allowed', [Auth::user(),'page.name'])
<li ng-class="{ active: properties.isActive('/feedback')}"><a href="#/feedback">Feedback</a></li>
@endcan
然后Laravel在调用策略的方法时复制用户参数,因为它调用方法的方式,请参阅\Illuminate\Auth\Access\Gate::resolvePolicyCallback
,第388行:
return call_user_func_array(
[$instance, $ability], array_merge([$user], $arguments)
);
正如您所看到的,它将使用传递的参数合并已解析的用户(它还会自行解析)。第一个传递的参数是当前用户。第二个是页面名称。最终将以下参数传递给策略的方法:User, User, 'page.name'
。前两个参数是相同的,我想摆脱这种重复。
我很高兴不从刀片服务器传递用户,但在这种情况下,Laravel无法解析策略,因为它通过第一个传递的参数查找策略!见\Illuminate\Auth\Access\Gate::firstArgumentCorrespondsToPolicy
,第346行:
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
因此,如果我没有将用户作为第一个参数传递,它会尝试按页面名称解析策略。我很困惑,请帮忙。
更新
我找到了一个笨拙的解决方案,使用带有policy()帮助器的刀片@if语句
@if(policy(Auth::user())->pageAllowed(Auth::user(),'feedback'))
<li ng-class="{ active: properties.isActive('/feedback')}"><a href="#/feedback">Feedback</a></li>
@endif
而不是@can语句。但我想知道我做错了什么。
答案 0 :(得分:0)
好吧,似乎我已经理解了重复用户模型的逻辑原因 - Laravel默认将当前用户作为第一个参数传递给所有策略。我为用户模型创建了一个策略,我必须在检查策略时传递模型。这就是重复发生的原因 - 第一个模型实例由框架传递,第二个模型实例由我传递。如果它是Post模型,参数将是:User,Post,......没有任何重复。