この記事では主に、VueJS アプリケーションでユーザー権限を管理する詳細なプロセスと方法、および関連するコードの表示について説明します。必要な友人は参照してください。
認証を必要とするフロントエンド アプリケーションでは、どのコンテンツを表示するかを決定するためにユーザー ロールを使用することがよくあります。たとえば、ゲストは記事を読むことができますが、編集ボタンを表示できるのは登録ユーザーまたは管理者だけです。
フロントエンドでの権限の管理は少し面倒になる場合があります。以前に次のようなコードを書いたことがあるかもしれません:
if (user.type === ADMIN || user.auth && post.owner === user.id ) { ... }
代わりに、シンプルで軽量なライブラリ - CASL - を使用すると、ユーザー権限の管理が非常に簡単になります。 CASL を使用して権限を定義し、現在のユーザーを設定している限り、上記のコードを次のように変更できます:
if (abilities.can('update', 'Post')) { ... }
この記事では、Vue.js と CASL を使用してフロントエンド アプリケーションの権限を管理する方法を示します。 。
CASL を使用すると、ユーザーに表示されるリソースを制限する一連のルールを定義できます。
たとえば、CASL ルールは、ユーザーが特定のリソースやインスタンス (投稿、記事、コメントなど) に対してどの CRUD (作成、読み取り、更新、削除) 操作を実行できるかを示すことができます。
案内広告 Web サイトがあるとします。最も明白なルールは次のとおりです:
訪問者はすべての投稿を閲覧できます
管理者はすべての投稿を閲覧でき、更新または削除できます
CASL を使用し、AbilityBuilder を使用してルールを定義します。新しいルールを定義するには can を呼び出します。例:
onst { AbilityBuilder } = require('casl'); export function(type) { AbilityBuilder.define(can => { switch(type) { case 'guest': can('read', 'Post'); break; case 'admin': can('read', 'Post'); can(['update', 'delete'], 'Post'); break; // Add more roles here } } };
これで、定義されたルールを使用してアプリケーションの権限を確認できるようになります。
import defineAbilitiesFor from './abilities'; let currentUser = { id: 999, name: "Julie" type: "registered", }; let abilities = defineAbilitiesFor(currentUser.type); Vue.component({ template: `<p><p> <p>Please log in</p> `, props: [ 'post' ], computed: { showPost() { return abilities.can('read', 'Post'); } } });
デモとして、広告投稿を表示するためのサーバー/クライアント アプリケーションを作成しました。このアプリケーションのルールは次のとおりです。ユーザーは投稿を読むことも投稿することもできますが、自分の投稿を更新または削除することしかできません。
Vue.js と CASL を使用して、これらのルールを簡単に実行および拡張しました。後で新しい操作やインスタンスが追加された場合でも便利です。
次に、このアプリケーションを構築する手順を説明します。見てみたい場合は、この Github リポジトリをチェックしてください。
ユーザー権限はresources/ability.jsで定義します。 CASL の利点の 1 つは、環境に依存しないことです。つまり、ブラウザだけでなくノードでも実行できることを意味します。
ノードの互換性を確保するために、権限の定義を CommonJS モジュールに書き込みます (Webpack を使用すると、このモジュールをクライアントで使用できるようになります)。
resources/ability.js
const casl = require('casl'); module.exports = function defineAbilitiesFor(user) { return casl.AbilityBuilder.define( { subjectName: item => item.type }, can => { can(['read', 'create'], 'Post'); can(['update', 'delete'], 'Post', { user: user }); } ); };
このコードを分析してみましょう。
define メソッドの 2 番目のパラメーターで、can を呼び出して権限ルールを定義します。このメソッドの最初のパラメータは許可する CRUD 操作で、2 番目のパラメータはリソースまたはインスタンス (この場合は Post) です。
2 番目の can 呼び出しでは、3 番目のパラメーターとしてオブジェクトを渡していることに注意してください。このオブジェクトは、ユーザー属性が提供されたユーザー オブジェクトと一致するかどうかをテストするために使用されます。これを行わないと、投稿を削除できるのは作成者だけではなく、誰でも自由に削除できてしまいます。
resources/ability.js
... casl.AbilityBuilder.define( ... can => { can(['read', 'create'], 'Post'); can(['update', 'delete'], 'Post', { user: user }); } );
CASL がインスタンスをチェックして権限を割り当てるときは、インスタンスのタイプを知る必要があります。 1 つの解決策は、define メソッドの最初のパラメータとして subjectName メソッドを持つオブジェクトを使用することです。subjectName メソッドはインスタンスのタイプを返します。
これは、インスタンスで型を返すことによって実現されます。 Post オブジェクトを定義するときに、このプロパティが存在することを確認する必要があります。
resources/ability.js
... casl.AbilityBuilder.define( { subjectName: item => item.type }, ... );
最後に、権限の定義を関数にカプセル化して、権限をテストする必要があるときにユーザー オブジェクトを直接渡すことができるようにします。次の関数で考えるとわかりやすいでしょう。
resources/ability.js
const casl = require('casl'); module.exports = function defineAbilitiesFor(user) { ... };
次に、フロントエンド アプリケーションのオブジェクトに対してユーザーがどのような CRUD 権限を持っているかを確認したいと思います。 Vue コンポーネントの CASL ルールにアクセスする必要があります。方法は次のとおりです:
Vue と能力プラグインを導入します。このプラグインは Vue プロトタイプに CASL を追加し、コンポーネント内で CASL を呼び出せるようにします。
ルールを Vue アプリケーションに導入します (例: resource/abilities.js)。
現在のユーザーを定義します。実際の戦闘では、サーバーを介してユーザー データを取得します。この例では、それをプロジェクトにハードコードするだけです。
能力モジュールは関数をエクスポートすることを思い出してください。それをdefineAbilitiesForと呼びます。ユーザー オブジェクトをこの関数に渡します。これで、可能な限りオブジェクトを調べて、現在のユーザーがどのような権限を持っているかを把握できるようになりました。
能力プラグインを追加して、this.$can(...) のようにコンポーネントでテストできるようにします。
src/main.js
import Vue from 'vue'; import abilitiesPlugin from './ability-plugin'; const defineAbilitiesFor = require('../resources/ability'); let user = { id: 1, name: 'George' }; let ability = defineAbilitiesFor(user.id); Vue.use(abilitiesPlugin, ability);
私たちのアプリケーションは案内広告投稿を使用します。投稿を表すこれらのオブジェクトはデータベースから取得され、サーバーによってフロントエンドに渡されます。例:
Post インスタンスには 2 つの属性が必要です:
type 属性。 CASL は、ability.js の subjectName コールバックを使用して、どのインスタンスがテストされているかを確認します。
user属性。这是发帖者。记住,用户只能更新和删除他们发布的帖子。在 main.js中我们通过defineAbilitiesFor(user.id)已经告诉了CASL当前用户是谁。CASL要做的就是检查用户的ID和user属性是否匹配。
let posts = [ { type: 'Post', user: 1, content: '1 used cat, good condition' }, { type: 'Post', user: 2, content: 'Second-hand bathroom wallpaper' } ];
这两个post对象中,ID为1的George,拥有第一个帖子的更新删除权限,但没有第二个的。
帖子通过Post组件在应用中展示。先看一下代码,下面我会讲解:
src/components/Post.vue
<template> <p> <p> <br /><small>posted by </small> </p> <button @click="del">Delete</button> </p> </template> <script> import axios from 'axios'; export default { props: ['post', 'username'], methods: { del() { if (this.$can('delete', this.post)) { ... } else { this.$emit('err', 'Only the owner of a post can delete it!'); } } } } </script> <style lang="scss">...</style>
点击Delete按钮,捕获到点击事件,会调用del处理函数。
我们通过this.$can('delete', post)来使用CASL检查当前用户是否具有操作权限。如果有权限,就进一步操作,如果没有,就给出错误提示“只有发布者可以删除!”
在真实项目里,用户在前端删除后,我们会通过 Ajax发送删除指令到接口,比如:
src/components/Post.vue
if (this.$can('delete', post)) { axios.get(`/delete/${post.id}`, ).then(res => { ... }); }
服务器不应信任客户端的CRUD操作,那我们把CASL测试逻辑放到服务器:
server.js
app.get("/delete/:id", (req, res) => { let postId = parseInt(req.params.id); let post = posts.find(post => post.id === postId); if (ability.can('delete', post)) { posts = posts.filter(cur => cur !== post); res.json({ success: true }); } else { res.json({ success: false }); } });
CASL是同构(isomorphic)的,服务器上的ability对象就可以从abilities.js中引入,这样我们就不必复制任何代码了!
此时,在简单的Vue应用里,我们就有非常好的方式管理用户权限了。
我认为this.$can('delete', post) 比下面这样优雅得多:
if (user.id === post.user && post.type === 'Post') { ... }
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上がVueJS でユーザー権限を設定する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。