Laravel 的授权原理讲解第一部分

33 篇文章 0 订阅

开始

$this->authorize('edits',$user);

这个方法是调用了Illuminate\Foundation\Auth\Access\AuthorizesRequests中的authorize方法:

public function authorize($ability, $arguments = [])
    {
        list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
        return app(Gate::class)->authorize($ability, $arguments);
    }

接着是Gate::class下的authorize方法:

public function authorize($ability, $arguments = [])
    {
        $result = $this->raw($ability, $arguments);
        if ($result instanceof Response) {
            return $result;
        }
        return $result ? $this->allow() : $this->deny();
    }

其中raw方法为:

protected function raw($ability,$arguments=[]){
    if(!$user=$this->resolveUser()){
        return false;
    }
    $arguments=array_merge($argument);
    $result=$this->callBeforeCallbacks($user,$ability,$arguments);
    if(is_null($result)){
        $result=$this->callAuthCallback($user,$ability,$arguments);
    }
    $this->callAfterCallbacks($user,$ability,$argument,$result);
    return $result;
}

其中重点之一就是resolveUser()这个函数,可是这个函数偏偏又是最模糊的存在:

protected function resolveUser(){
    return call_user_func($this->userResolver);
}

接着问题就很奇怪了,这个参数是在Gate类的构造函数中指定的,可是外界又是通过服务容器的全局函数app()调用的该类,那么我怎么知道该userResolver参数在哪里呢?于是我调用了PHPStorm的全局内容搜索:Ctrl+Shift+F,找到了其传入到服务容器中时设置的函数:

//该函数位于 Illuminate\Auth\AuthServiceProvider.php 中
protected function registerAccessGate()
    {
        $this->app->singleton(GateContract::class, function ($app) {
            return new Gate($app, function () use ($app) {
                return call_user_func($app['auth']->userResolver());
            });
        });
    }

这里的GateContract::class其实是在命名空间中使用了别名,原始名称是:Illuminate\Contracts\Auth\Access\Gate,是不是!就问是不是我们的Gate类!!!

所以下一个问题就是这个$app['auth']->userResolver()是什么了,在\Illuminate\Foundation\Application.php中,我们找到了答案:

'auth'=> [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],

所以我们去看AuthManager类中的userResolver方法:

public function userResolver()
    {
        return $this->userResolver;
    }

肯定是在构造函数中指定了该参数:

public function __construct($app)
    {
        $this->app = $app;

        $this->userResolver = function ($guard = null) {
            return $this->guard($guard)->user();
        };
    }

WTF,这是什么鬼!!!我只是想知道一个函数而已,要不要这么玩我啊!!!没办法,继续跟进,于是就去搜这个user()是什么鬼:

    public function user()
    {
        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        return $this->user = call_user_func(
            $this->callback, $this->request
        );
    }

这个类的使用情况有点超出授权的范畴了,之后再讨论,经过上面的过程,我们知道了一个情况,在最开始的$user=$this->resolveUser()返回的$user是经过Laravel确认的当前身份用户

return is_callable([$policy, $ability])
                        ? $policy->{$ability}($user, ...$arguments)
                        : false;

调用了Policies文件下的

public function edits(User $currentUser,User $user){
      return $currentUser->id===$user->id;
    }

这样的形式,所以第一个$currentUser是根据guard的中间件来的,这部分后面再讨论,而后一个$user则是我们在控制器中传入的参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值