这是教程的第三遍,所以想弄的更加清楚。删除回复权限控制方法,源码疑问 ??

首先创建 ReplyPolicy 策略类,然后创建指定的方法

ReplyPolicy.php 
public function destroy(User $user, Reply $reply)
    {
      //  在策略类中加入 destroy 方法
        return $user->isAuthorOf($reply) || $user->isAuthorOf($reply->topic);
     }

创建完成后, 在 RepliesController 类中使用策略类定义的方法

public function destroy(Reply $reply)
    {
        开始分析这行代码
        $this->authorize('destroy', $reply);

        $reply->delete();

        return redirect()->to($reply->topic->link())->with('success', '删除成功');
    }

$this->authorize('destroy',$reply)

<?php

namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
    是调用 AuthorizesRequests 这个类中的方法
}

AuthorizesRequests 类中 authorize() 方法

public function authorize($ability, $arguments = [])
    {
        // $this->authorize('destroy', $reply);

        list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
        dd($arguments);
        我 dd 了 app(Gate::class) 打印出一大堆东西没有看明白
        dd($ability) ==> 'destroy'
        dd($arguments) ==> Reply 这个类
        return app(Gate::class)->authorize($ability, $arguments);
    }

现在我找到这个方法,但是我不知道这个方法怎么和 ReplyPolicy 中的 destroy() 方法做关联

希望 哪位好心人,给解答下嘛,谢谢谢谢啦。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 8

这方面的分析还没研究过,没法回答啊。反正我只是了解怎么用(1.生成策略;2.注册策略;3.使用策略判断是否授权)具体怎么实现的逻辑没关注。用框架除非你要对框架2次开发,否则,会用就好。

2年前 评论

你dd(app('xxx'))出来应该可以看到是某个类吧,该类里面应该有authorize这个方法吧,进去看看?

2年前 评论

file
这里调用了Gate了,看这个类的authorize这个方法

2年前 评论

@shmily 但是怎么和 ReplyPolicy 联系起来呢?

2年前 评论

@Gebriel

file

provider这里绑定了,应该是根据authorize传进去的$order识别到OrderPolicy

2年前 评论

@shmily 对耶,我早上看到,我也没有想到 传进去的类,来绑定这个,权限模型。谢谢谢谢,
脑筋有时候就不会转,所以才会在阅读教程的时候多想想,然思维开阔起来。
你确定是这样的吗?
哈哈

2年前 评论

@shmily 我刚刚又看了下。

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
         \App\Models\Reply::class => \App\Policies\ReplyPolicy::class,
         \App\Models\Topic::class => \App\Policies\TopicPolicy::class,
        'App\Model' => 'App\Policies\ModelPolicy',
        \App\Models\User::class => \App\Policies\UserPolicy::class,
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        // 这里掉用 下面的方法
        $this->registerPolicies();

        //
    }
}
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [];

    /**
     * Register the application's policies.
     *
     * @return void
     */
    public function registerPolicies()
    {
        foreach ($this->policies as $key => $value) {
            Gate::policy($key, $value);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function register()
    {
        //
    }
}
2年前 评论
pardon110

实际上app函数解析得到Illuminate\Auth\Access\Gate类实例,关键是raw方法的使用

    // Illuminate\Auth\Access\Gate.php 控制器内调用authorize方法,进相关trait, 终归入此法
    public function authorize($ability, $arguments = [])

然后在该authorize方法内,又调用了raw方法,主要做了以下三件事

   public function raw($ability, $arguments = [])
    {
        $arguments = Arr::wrap($arguments); 

        $user = $this->resolveUser(); //获取当前认证用户实例

        // 1.首先,执行Gate的前置过滤回调,若有非null值返回,执行认证回调结果
        $result = $this->callBeforeCallbacks(
            $user, $ability, $arguments
        );
        // 2.其次,调用认证回调,在此期间会更根据资源模型推断对应的策略类,进而结合策略方法名进行调用
        if (is_null($result)) {
            $result = $this->callAuthCallback($user, $ability, $arguments);
        }
        // 3.后置回调,调用在Gate门面上注册与模型无关的闭包,可以做一些日志分析的动作
        return $this->callAfterCallbacks(
            $user, $ability, $arguments, $result
        );
    }

其中步骤2会通过参数推断(通过在auth服务提供者时注$policies属性,模型类(参数类型)/策略类数组映射信息),分析得到策略类实例,然后调用对应的策略方法。

1年前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!