memdev / laravel-frontend-policy
在前端使用 Laravel 的授权。
Requires
- php: ^7.2.5 | ^8.0
- laravel/framework: ^6.0 || ^7.0 || ^8.24 || ^9.0
Requires (Dev)
- fzaninotto/faker: ^1.9.1
- laravel/laravel: ^8.0 || ^9.0
- mockery/mockery: ^1.3.1
- phpunit/phpunit: ^9.0
README
在前端使用 Laravel 的授权。
一个用于 SPA 和前端重量级应用的优秀工具。
如果你想了解该包的内部实现,我们建议阅读以下文章: 在 Laravel 前端实现授权。
目录
入门
您可以使用 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
对象需要一个传递的用户才能正常工作。这可以是 string
或 object
。默认情况下,它会查找 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 形状的优雅模型,因此模型必须使用生成正确模型名称的 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
目录中生成。
注意,该命令将自动将
Policy
附加到文件名中。这意味着您可以在运行命令时仅传递模型名称。
在生成策略文件后,请使用 npm
编译所有 JavaScript,包括策略。
重要!
策略会自动注册。这意味着不需要手动导入它们。门实例将 自动 填充策略。每个策略都将与模型的 model_name
属性匹配的位置使用。
根据 Laravel 的默认 app.js,当调用 npm run dev
、npm run prod
等等时,门实例会自动注册策略。
编写策略规则
策略,就像在 Laravel 中一样,默认有以下方法:viewAny
、view
、create
、update
、restore
、delete
和 forceDelete
。当然,您也可以使用自定义方法,策略是完全可定制的。
... 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>
贡献
如果您发现了一个错误或对软件包有想法,请随时提交问题。