此包已被弃用且不再维护。未建议替代包。

在客户端使用 Laravel 的授权。

安装: 2,553

依赖者: 0

建议者: 0

安全: 0

星标: 97

关注者: 7

分支: 7

开放问题: 0

类型:项目

v0.4.1 2021-03-02 07:19 UTC

This package is auto-updated.

Last update: 2022-05-29 01:39:00 UTC


README

在客户端使用 Laravel 的授权。

适用于单页应用和前端密集型应用的优秀工具。

如果您想了解包背后的内容,我们建议阅读这篇文章: 在客户端实现 Laravel 的授权

目录

  1. 入门
  2. 发布和设置 JavaScript 库
  3. 使用策略和 Gate.js
  4. 示例
  5. 贡献

入门

您可以使用 composer 安装此包,运行 composer require thepinecode/policy 命令。

由于该包支持自动发现,Laravel 将在幕后自动注册服务提供程序。

在某些情况下,您可能需要禁用此包的自动发现。您可以将提供程序类添加到 dont-discover 数组中,以禁用它。然后您需要手动重新注册它。

发布和设置 JavaScript 库

默认情况下,该包提供了一个 Gate.js 文件,用于处理策略。使用 php artisan vendor:publish 命令并选择 Pine\Policy\PolicyServiceProvider 提供程序。发布后,如果使用 Laravel 5.7+,您可以在 resources/js/policies 文件夹中找到您的最新副本。如果您的应用程序低于 5.7,JS 将发布在 resources/assets/js/policies

设置 Gate.js

然后您可以将 Gate 类导入并分配给 window 对象。

import Gate from './policies/Gate';
window.Gate = Gate;

初始化 gate 实例

从这一点开始,您可以从应用程序的任何地方初始化翻译服务。

let gate = new Gate;

将用户传递给 gate 实例

Gate 对象需要传递的用户才能正常工作。这可以是 stringobject。默认情况下,它查找 window['user'] 对象,但您可能需要自定义键或对象本身。

let gate = new Gate; // window['user']

let gate = new Gate('admin'); // window['admin']

let gate = new Gate({ ... }); // uses the custom object

注意,您可以传递任何对象作为 用户。如果您传递团队或组对象,它也可以正常工作。由于您在 Gate 后定义了逻辑,您可以传递任何您想要的。

将 Vue 服务化使用

如果您想直接从 Vue 模板中使用它,您可以轻松地扩展 Vue。

Vue.prototype.$Gate = new Gate;
<template>
    <div v-if="$Gate.allow('view', model)">...</div>
</template>
computed: {
    hasPermission: {
        return this.$Gate.allow('view', this.model);
    }
}

@currentUser Blade 指令

为了使其更快捷,该软件包包含一个 @currentUser Blade 指令。这个指令除了打印当前认证用户作为 JSON 并将其分配给 window 对象外,不做任何其他事情。

@currentUser

<!-- Result -->
<script>window['user'] = { ... };</script>

您可以覆盖用户的默认键。您可以通过传递一个字符串给 Blade 指令来实现。

@currentUser ('admin')

<!-- Result -->
<script>window['admin'] = { ... };</script>

如果没有认证用户,则值将为 null

使用策略和 Gate.js

可用方法

allow()

allow() 接受两个参数。第一个是要执行的操作,第二个是 模型对象模型名称,类似于 Laravel。

注意:模型名称 应该是 Laravel 中实际模型名称的小写版本:例如,Comment 变为 comment

gate.allow('view', model);

gate.allow('create', 'comment');

deny()

deny()allow() 有相同的签名,但它将否定其返回值。

gate.deny('view', model);

gate.deny('create', 'comment');

before()

与 Laravel 类似,在 before() 方法中,您可以提供自定义逻辑来检查特殊条件。如果条件通过,则 allow()deny() 中的其余策略规则将不会运行。然而,如果条件失败,策略规则将生效。要使用 before() 方法,您可能需要扩展 gate 对象并定义您的自定义逻辑。

Gate.prototype.before = function () {
    return this.user.is_admin;
}

请注意,为了正确使用 this 对象,请使用传统的函数签名而不是箭头函数 ((() => {}) 函数)。

UsesModelName 特性添加到模型中

由于策略使用真实的 JSON 形状的 eloquent 模型,因此模型必须使用 Pine\Policy\UsesModelName 特性来生成正确的模型名称。此模型名称属性由 Gate.js 用于将正确的策略与模型配对。

use Pine\Policy\UsesModelName;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    use UsesModelName;

    protected $appends = ['model_name'];
}

请注意,为了能够在前端使用此属性,该属性必须附加到 JSON 表单中。您可以在 文档 中了解更多关于向 JSON 附加值的信息。

使用 artisan 生成策略

该软件包默认包含一个 artisan 命令,可以帮助您轻松生成 JavaScript 策略。要创建策略,请运行 php artisan make:js-policy Model 命令,其中 Model 是模型名称。

php artisan make:js-policy Comment

此命令将在 resources/js/policies 目录中创建与 Gate.js 旁边的 CommentPolicy.js 文件。如果您使用的 Laravel 版本低于 5.7,策略将在 resources/assets/js/policies 目录中生成。

请注意,命令将自动在文件名中追加策略。这意味着您在运行命令时只需要传递模型名称。

在您生成了策略文件后,使用npm编译所有JavaScript,包括策略。

重要!

策略将自动注册。这意味着不需要手动导入。网关实例将自动填充策略。每个策略都将用于与模型的model_name属性匹配的地方。

基于Laravel的默认app.js,网关实例在调用npm run devnpm run prod等时,将自动注册策略

编写策略规则

策略(如Laravel中)默认具有以下方法:viewAnyviewcreateupdaterestoredeleteforceDelete。当然,您也可以使用自定义方法,策略是完全可定制的。

...

view(user, model)
{
    return user.id == model.user_id;
}

create(user)
{
    return user.is_admin;
}

approve(user, model)
{
    return user.is_editor && user.id == model.user_id;
}

...

示例

// app.js
Vue.prototype.$Gate = new Gate;

Vue.component('posts', {
    mounted() {
        axios.get('/api/posts')
            .then(response => this.posts = response.data);
    },
    data() {
        return {
            posts: [],
        };
    },
    template: `
        <ul><li v-for="post in posts" v-if="$Gate.allow('update', post)"></li></ul>
        <button v-if="$Gate.allow('create', 'post')">Create post</button>
    `
});

let app = new Vue({
    //
})
<body>
    <posts></posts>

    @currentUser
    <script src="{{ asset('js/app.js') }}"></script>
</body>

贡献

如果您发现了一个错误或者有关于这个包的想法,请随时提交一个issue。