web-dev-qa-db-ja.com

MongoDB + Node JS + Role Based Access Control(RBAC)

現在MEANを学習していますスタック、単純なTODOアプリを開発していて、そのためにロールベースのアクセス制御(RBAC)を実装したいと考えています。 MongoDBでロールと権限を設定するにはどうすればよいですか?.

私は3つの役割が必要です(役割はおかしそうに見えるかもしれませんが、これは純粋に学ぶためのものです):

  • スーパーヒーロー
  • MAN

[〜#〜] god [〜#〜]-スーパー管理者と同様に、アプリケーションで何でも実行できます。 TODOおよび他のユーザーのC、R、U、D権限。 TODOを作成してSUPER HEROまたはMANに直接割り当てることができます。TODOまたはユーザーをいつでも更新または削除できます。

SUPER HERO-管理者に似ており、彼の個人データに対して何でも実行する超能力を持っています-TODOのC、R、U、D。ユーザーを作成できません。 GODによって作成され、GODに割り当てられたTODOの読み取りとコメントの追加のみが可能です。

[〜#〜] man [〜#〜]-自分に割り当てられたTODOの読み取りとコメントの追加のみが可能.

要約すると:

GOD - C,R,U,D [Global Level] SUPER HERO - C,R,U,D [Private] + R,U [Assigned to him] MAN - R,U [Assigned to him]

USERS&ROLESコレクションが必要だと理解しています。 ROLESの順番には、PERMISSIONSなどが必要です。それらをすべて配線するにはどうすればよいですか?

15
BeingSuman

私は役割に付けられた名前が好き-GOD、SUPER HERO&MAN、わかりやすい

MEANスタックを使用していて、ルート検証の多くがnodeで発生するため、ロールテーブルをシンプルに保つことをお勧めします。

役割:

_{
_id : 1,
name : GOD,
golbalPerms : true
},
{
_id : 2,
name : SUPER HERO,
privatePerms : true
},
{
_id : 3,
name : MAN
}
_

ユーザー:

_{
_id : 111,
name : Jesus,
roleId : 1
},
{
_id : 222,
name : BatMan,
roleId : 2
},
{
_id : 333,
name : Jack,
roleId : 3
}
_

ユーザーがログインしてuserオブジェクトをクライアントに送り返すときは、roleIdを対応するDBのroleオブジェクトに置き換えてください。

Node JS:のコードに参加する

ユースケースを完全に理解することで、次の方法に分類できます-

  • ユーザーを作成

  • CreateTodo

  • DeleteTodo

  • ReadTodo

  • UpdateTodo
  • コメント

  • AssignTodo

段階的に進みましょうCreateUser

ルートコードスニペット:

_app.all('/users', users.requiresLogin);

// Users Routes
app.route('/users')
    .post(users.hasPerms('globalPerms'), users.create);
_

コントローラーで、入力globalPermsに基づいて検証できます。検証された場合、対応するエラーメッセージでnext() else returnを呼び出してユーザーを作成できます。

CreateTodo && DeleteTodo

どちらも、小さなトリックでほとんど同じロジックを処理します。

ルートコードスニペット:

_app.all('/todos', users.requiresLogin);

// Users Routes
app.route('/todos')
    .post(users.hasPerms('globalPerms','privatePerms'), todos.create);
    .delete(users.hasPerms('globalPerms','privatePerms'), todos.delete);
_

Todoを作成する場合、globalPerms[〜#〜] god [〜#〜]であり、privatePermsSUPER HEROであり、どちらも許可できます。

ここでのトリックは_todos.delete_メソッドにあります。_user.id === todos.createById_を確認してください。そうしないと、SUPER HEROがGODによって作成されたTodoを削除する可能性があります。

ReadTodo

[〜#〜] todo [〜#〜]が作成されると、[〜#〜] todo [〜#〜の場合と同様に、createByIdが保存されます。 ]が誰かに割り当てられている場合、assignedToおよびassignedByも記録する必要があります。

これにより、他の多くの操作が扱いやすくなります。

_user.role.globalPerms_-すべてのTODOデータをGODに提供します。

_user.role.privatePerms_-TODOにcreatedBy彼または彼女または彼/彼女に割り当てられたものを与えます。

_user.role.globalPerms === undefined && user.role.privatePerms === undefined_-そのMANと彼にのみ割り当てられているTODOを与える.

pdateTodo&CommentTodo

これはReadTODOがDIYで行っていることの正確なレプリカです

最後に、AssignTodo

単純なもの、_loggedInUser.id === todos.createdById_なら、誰にでも割り当てることができます。

ここで覚えておくべき2つのこと:

  1. 一部の割り当ては主にUI(Angular)フロントで行われるため、_loggedInUser.id === todos.createdById_をチェックするというアプローチを採用しました。ログインしたユーザーは、何らかの方法ですべてのTODOを読み取り操作で表示し、好きな人に割り当てることができます。

  2. SUPER HEROがTODOを自分または他のSUPER HEROまたはMANにのみ割り当てることができますが、GODには割り当てられないことを確認してください。UIフロントで[割り当て]オプションを表示する方法これはこの質問の範囲外です。これはあくまでも問題です。

これが明確であることを願っています。

注:MAN Rolesコレクション内にアクセス許可を与える必要はなく、すべての可能な操作を管理せずに実行しました。

22
swetha akula

これは非常に広範な質問であり、さまざまな方法で解決できます。

MEANスタックを使用していることを追加したので、私の質問をそれに限定します。

質問全体に含まれていないことの1つは、使用している認証アーキテクチャの種類です。トークンベースの認証を使用しているとしましょう。一般に、最近の人々はそれを使用しています。

3種類のユーザーがいます。トークンのタイプを区別するために使用できるさまざまなオプションもあります。

  1. 保存される異なるコレクション(mongoDB)またはRedisセット
  2. 暗号化されたトークンには、ユーザーのタイプなども含まれます(これは、トークンをバックエンドに格納する必要がない場合に便利です。復号化して確認するだけです)

    • それはユースケースに完全に依存します。

ユーザーの特定のルートへのエントリを許可する前に、トークンを最初に確認していることを確認してください。

app.post('/godlevelroute', godtokencheck, callrouteandfunction);
app.post('/superherolevelroute', superheroroute, callrouteandfunction);

angularからヘッダーでトークンを送信する必要があります。その後、ヘッダーからデータを取り出し、その特定のユーザーがそのルートを通過する権限を持っているかどうかを確認できます。

神レベルのユーザーがログインしている場合、彼は彼と一緒にgodleveltokenを持ち、そのルートへのアクセスを許可する前に最初にそれをチェックします。そうでない場合は、エラーメッセージを表示できます。

これは、サーバー側のサンプルトークンチェック関数にすることができます

function checkToken(req, res, next) {
var token = req.headers['accesstoken']; //access token from header
//now depending upon which system you are following you can run a check
};

ノードモジュールの提案: https://www.npmjs.com/package/jsonwebtoken

今フロントエンド部分に来ています。 angular)を使用しているため、ページを表示する前にトークンを傍受できます。

このブログを読んで、私が説明しようとしたことを図で表すことができます。 ここをクリック

2

可能なアプローチ->ユーザーコレクション/スキーマに埋め込まれた役割を持つ:ユーザードキュメントには次のものが必要です:

{
    _id : "[email protected]",
    name: "lorem ipsum",
    role: "MAN"
}

あなたの投稿が説明する限り、神だけがTODOを作成して割り当てることができます。 Rolesコレクションは以下を保持します。

{
    _id : "MAN",
    globalPerm: [],
    privatePerm: [],
    assignedPerm: ["r","u"],
},
{
    _id : "SUPER_HERO",
    globalPerm: [],
    privatePerm: ["c","r","u","d"],
    assignedPerm: ["c","r","u","d"],
},
{
    _id : "GOD",
    globalPerm: ["c","r","u","d"],
    privatePerm: ["c","r","u","d"],
    assignedPerm: ["c","r","u","d"],
}

Node JS Middlewaresユーザーの正しい権限値を取得した後、ミドルウェアを使用することができます。エクスプレスHTTPリクエストルートの例:

app.post('/updateTodo', permissions.check('privatePerm', 'c'), function (req, res) {
 // do stuff

};

tODOを更新するために実際に関数本体を実行する前に、permissions.checkが呼び出されます。

したがって、ユーザーがToDoを更新しようとすると、最初に対応する権限が確認されます。

0
inaitgaJ