检查Laravel政策

时间:2016-08-09 14:19:37

标签: php laravel laravel-5 laravel-5.2

我在策略中有一个检查用户是否可以访问页面的方法。页面名称和当前用户是策略方法的参数:

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语句。但我想知道我做错了什么。

1 个答案:

答案 0 :(得分:0)

好吧,似乎我已经理解了重复用户模型的逻辑原因 - Laravel默认将当前用户作为第一个参数传递给所有策略。我为用户模型创建了一个策略,我必须在检查策略时传递模型。这就是重复发生的原因 - 第一个模型实例由框架传递,第二个模型实例由我传递。如果它是Post模型,参数将是:User,Post,......没有任何重复。