当前位置:  开发笔记 > 编程语言 > 正文

Laravel用户功能

如何解决《Laravel用户功能》经验,为你挑选了2个好方法。

在Laravel中,您可以轻松定义功能,然后在用户请求中挂钩,以执行不同的操作:

$gate->define('update-post', function ($user, $post) {
    return $user->id === $post->user_id;
});

但几乎所有我定义的能力都包含$user->id === $model->user_id在其中.我不喜欢它,因为它是一种重复的条件,我认为它可能更抽象.

我定义的大部分功能都是根据更新/删除记录,所以如果我可以将全局条件应用于所有这些记录,或者如果可以有一个组能力定义哪个类似于我们在路由中所做的那样,那么会更好.

它有什么解决方法吗?我真的很喜欢干.



1> Blue Genie..:

Laravel中的所有东西都是可扩展的,这是其服务提供商的力量.

您可以将Gate对象扩展到对象,MyCustomGate并在该对象中执行任何操作.这是一个例子:

MyCustomGate.php

class MyCustomGate extends \Illuminate\Auth\Access\Gate
{
    protected $hasOwnershipVerification = [];

    /**
     * Define a new ability.
     *
     * @param  string  $ability
     * @param  callable|string  $callback
     * @return $this
     *
     * @throws \InvalidArgumentException
     */
    public function defineWithOwnership($ability, $callback, $foreignUserIdKey = "user_id")
    {
        // We will add this 
        $this->hasOwnershipVerification[$ability] = $foreignUserIdKey;

        return $this->define($ability, $callback);
    }

    /**
     * Resolve and call the appropriate authorization callback.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @return bool
     */
    protected function callAuthCallback($user, $ability, array $arguments)
    {
        $callback = $this->resolveAuthCallback(
            $user, $ability, $arguments
        );

        // We will assume that the model is ALWAYS the first key
        $model = is_array($arguments) ? $arguments[0] : $arguments;

        return $this->checkDirectOwnership($ability, $user, $model) && call_user_func_array(
            $callback, array_merge([$user], $arguments)
        );
    }

    /**
     * Check if the user owns a model.
     *
     * @param  string  $ability
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return bool
     */
    protected function checkDirectOwnership($ability, $user, $model)
    {
        if(!isset($this->hasOwnershipVerification[$ability])) {
            return true
        }

        $userIdKey = $this->hasOwnershipVerification[$ability];

        // getAuthIdentifier() is just ->id, but it's better in case the pk of a user is different that id
        return $user->getAuthIdentifier() == $model->{$userIdKey};
    }
}

然后,你必须告诉Laravel使用你的门而不是默认门.你可以在你的那个AuthServiceProvider(假设它正在扩展Illuminate\Auth\AuthServiceProvider,只需添加以下方法).

AuthServiceProvider

/**
 * Register the access gate service.
 *
 * @return void
 */
protected function registerAccessGate()
{
    $this->app->singleton(\Illuminate\Contracts\Auth\Access\Gate::class, function ($app) {
        return new MyCustomGate($app, function () use ($app) {
            return $app['auth']->user();
        });
    });
}

这样,您可以使用defineWithOwnership()方法而不是使用方法来定义能力define().您仍然可以使用define()不需要所有权验证的功能.第三个参数defineWithOwnership()接受的是$foreignUserIdKey; 当模型具有用户id的不同字段时,用于该情况.

注意:我在运行中编写了代码并没有尝试,它可能有错误,但你明白了.



2> Tzook Bar No..:

我检查了你的问题很多,但我发现没有"简单"的方法.

相反,我可能会这样做:

id === $model->user_id;
        if ($owned === false)
             throw new NotOwnedException;
    }    
 }

 class PostPolicy
 {

     use CheckOwnership;

    public function update(User $user, Post $post)
    {
         try {
             $this->checkOwnership($user, $post);
             //continue other checks
         } catch (NotOwnedException $ex) {
             return false;
         } 
    }
 }

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有