php - Laravel 用户能力

标签 php laravel laravel-5.1

在 Laravel 中你可以很容易地 define abilities然后在用户请求执行不同的操作时挂接到它们:

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

但几乎所有我定义的能力都有这部分 $user->id === $model->user_id 在里面。我不喜欢它,因为它是一种一遍又一遍地重复我认为可能更抽象的条件。

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

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

最佳答案

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 字段的情况。

注意:我是即时编写的代码,没有尝试,可能有错误,但你明白了。

关于php - Laravel 用户能力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34375042/

相关文章:

PHP 使用 array_keys( ) 获取嵌套数组中的键

mysql - Laravel 关系查询返回相关 ID 而不是主 ID

php - 无法在 not like 子句 Laravel 中传递多个值

php - 无法通过 php mail() 发送邮件

php - 从 PHP 文件在后台运行 Python 脚本

mysql - Laravel 登录超时

mysql - 在 laravel 5.1 注册期间将 IP 地址存储在数据库中

javascript - 如何过滤选择选项中的数据并将其显示为报告(php : laravel framework)

php - 在 laravel 中获取在线用户

laravel - Laravel 中使用 mailgun 发送电子邮件错误