現在MEANを学習していますスタック、単純なTODOアプリを開発していて、そのためにロールベースのアクセス制御(RBAC)を実装したいと考えています。 MongoDBでロールと権限を設定するにはどうすればよいですか?.
私は3つの役割が必要です(役割はおかしそうに見えるかもしれませんが、これは純粋に学ぶためのものです):
[〜#〜] 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などが必要です。それらをすべて配線するにはどうすればよいですか?
私は役割に付けられた名前が好き-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
コメント
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 [〜#〜]であり、privatePerms
はSUPER 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つのこと:
一部の割り当ては主にUI(Angular)フロントで行われるため、_loggedInUser.id === todos.createdById
_をチェックするというアプローチを採用しました。ログインしたユーザーは、何らかの方法ですべてのTODOを読み取り操作で表示し、好きな人に割り当てることができます。
SUPER HEROがTODOを自分または他のSUPER HEROまたはMANにのみ割り当てることができますが、GODには割り当てられないことを確認してください。UIフロントで[割り当て]オプションを表示する方法これはこの質問の範囲外です。これはあくまでも問題です。
これが明確であることを願っています。
注:MAN Rolesコレクション内にアクセス許可を与える必要はなく、すべての可能な操作を管理せずに実行しました。
これは非常に広範な質問であり、さまざまな方法で解決できます。
MEANスタックを使用していることを追加したので、私の質問をそれに限定します。
質問全体に含まれていないことの1つは、使用している認証アーキテクチャの種類です。トークンベースの認証を使用しているとしましょう。一般に、最近の人々はそれを使用しています。
3種類のユーザーがいます。トークンのタイプを区別するために使用できるさまざまなオプションもあります。
暗号化されたトークンには、ユーザーのタイプなども含まれます(これは、トークンをバックエンドに格納する必要がない場合に便利です。復号化して確認するだけです)
ユーザーの特定のルートへのエントリを許可する前に、トークンを最初に確認していることを確認してください。
例
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)を使用しているため、ページを表示する前にトークンを傍受できます。
このブログを読んで、私が説明しようとしたことを図で表すことができます。 ここをクリック
可能なアプローチ->ユーザーコレクション/スキーマに埋め込まれた役割を持つ:ユーザードキュメントには次のものが必要です:
{
_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を更新しようとすると、最初に対応する権限が確認されます。