2012-02-22 7 views
21

express.jsの役割ベースの承認にはどのような戦略が適していますか?特に明示的なリソース? Express-resourcenode.jsとexpress.jsでのグループ/ルールベースの承認アプローチ

そこにはハンドラがありませんので、私は3つのオプションがあると思う:

  1. は、リソースへの認証機能をパスし、各リソース要求別途
  2. チェック権限を確認するミドルウェア
  3. を使用します認証直後のすべてのリクエスト

他に解決策はありますか?

グループ/ロールベースの認証は、かなりアンティークなアプローチです。アクセス制御の新しい方法がありますか?そうでない場合は、どのように役割ベースの認可をnode.jsに適用できますか?グループルール関係をどこに格納するか(NoSQL/CouchDB/Redisを使用)一例として、

、構造:

/ 
    /forums 
    /forums/threads 

各リソースインデックス、新しい、作成、ショー、編集、更新および破壊と。いくつかの人々はスレッドやフォーラムを編集/削除することができます。

答えて

11

Connect-roles簡単な、非常に良いですし、ドキュメントも非常に明確です。

var user = roles; 

app.get('/profile/:id', user.can('edit profile'), function (req, res) { 
    req.render('profile-edit', { id: req.params.id }); 
}) 
app.get('/admin', user.is('admin'), function (req, res) { 
    res.render('admin'); 
} 
3

エクスプレスでは、前提条件の検証を行うことができるすべての演算子(http://expressjs.com/guide.html#passing-routeコントロール)にフックするハンドラを追加できます。ここでは、HTTP verb(PUT、DELETEなど)またはURL(param('op')は「編集」など)に基づいて、ユーザーの役割を取得してアクセスを制限できます。

app.all('/user/:id/:op?', function(req, res, next){ 
    req.user = users[req.params.id]; 
    if (req.user) { 
    next(); 
    } else { 
    next(new Error('cannot find user ' + req.params.id)); 
    } 
}); 
+0

このように、明示的リソースでは機能しません。 – Patrick

32

それは(少なくともないクリーンな方法で)ルート固有のミドルウェアを許可しないので、私は、それが明示-リソースを使用してクリーンな方法でこれを解決するのは難しいと言うでしょう。

私はエクスプレスリソースモジュールと同様のレイアウトを選択しますが、それは簡単な古い表現でルーティングします。このような何か:

// Resource 
var forum = { 
    index: // ... 
    show: // ... 
    create: // ... 
    update: // ... 
    destroy: // ... 
}; 

// Middleware 
var requireRole = function(role) { 
    return function(req, res, next) { 
    if('user' in req.session && req.session.user.role === role) 
     next(); 
    else 
     res.send(403); 
    } 
}; 

// Routing 
app.get('/forums', forum.index); 
app.get('/forums/:id', forum.show); 
app.post('/forums', requireRole('moderator'), forum.create); // Only moderators can create forums 
app.delete('/forums/:id', requireRole('admin'), forum.destroy); // Only admins can delete forums 

UPDATEは:急行・リソース、例えばルート固有のミドルウェアに関する継続的な議論が行われてきましたhere。現行ビューは例えば、アクションごとの配列を持っているように思わ:

var forums = { 
    index: [ requireRole('foo'), function(req, res, next) { ... } ] 
}; 

あなたはプル要求を通じて見て、あなたが使用できるものがあるかどうかを確認できます。もちろん、あなたがそれに慣れていなければ、私はそれを完全に理解しています。私は将来、明示的リソースでこれを見ることができると確信しています。

app.delete('*', requireRole('admin')); // Only admins are allowed to delete anything 
app.put('/forums/*', requireRole('moderator')); // Only moderators are allowed to update forums 
:私は考えることができる

唯一の他のソリューションは、エクスプレス・リソースとリソースをマウントしますが、ミドルウェアは、その「外」付属持って、何かすることですヤンJongboomの答え、のラインに沿っています

しかし、このURLにはURLが漏れていることは残念です。

+0

問題はかなりの量のリソースがあり、それは速達リソースではきれいだということです。私はapp.use()で使用できる小さなモジュールについて考えていますが、これを書く方法はわかりません。 – Patrick

+0

パトリック、私は全く同意します。詳しくは上記の私の更新を見てください。これに関して私が参照するものより多くのプル要求があります。私はそれについては分かりませんが、TJが3.0より後になると、エクスプレスリソース、express-namespace&coについてより多くのことが働くだろうという気持ちがあります。 –

2

モジュールを非明示的ルーティングミドルウェアとして書きました。高速ルートでうまく動作します。

Gandalf on GitHub

+0

ミドルウェアの@Patrickに感謝します。 expressjsでそれを使用する方法の良い例がありますか?申し訳ありませんが、noobsの質問のように聞こえたら、私はnodejsにかなり新しくて、表現しています。 例は大変お世話になります – praneybehl

+0

@praneybehl私はconnect-rolesやLinusのアプローチをお勧めします。 Gandalfミドルウェアは古くなっています。 – Patrick

26

私は同じ質問を研究しており、いくつかの良いモジュールを見つけました。私はここで見つけることができるnode-aclパッケージに焦点を当てています。 https://github.com/optimalbits/node_acl

このパッケージはACLパターンを非常に理解しやすい方法で実装しているようで、ノード/エクスプレスアプリケーションに簡単に統合する方法を提供しています。

まず、リソース、役割、およびアクセス許可を定義する必要があります。

たとえば、リソースが使用できます

/ 
    /forums 
    /forums/threads 

役割は、この例では

public 
admin 
user 
    john 
    jane 

をすることができ、役割ジョンとジェーンは、実際のユーザーアカウントにマップすることができますが、彼らは継承しますユーザーロールのすべてのアクセス許可リソース

  • 権限は

  • を作成、更新
  • を示し

またはあなたの標準的なCRUD操作を破壊します。

これでこれらが定義されたので、node-aclを使用してaclを設定する方法を見てみましょう。これらのノートは、パッケージ

var acl = require('acl'); 

があなたのバックエンドをセットアップし

インポートドキュメントから派生しています。私のアプリは、MongoDBのを使用しているが、ノード-ACLパッケージはDBINSTANCE今すぐに私たちの役割を追加することができますmongoose.connection.db

に置き換えられるように、私のアプリはマングースを使用している他のストレージメカニズムに

acl = new acl(new acl.mongodbBackend(dbInstance, prefix)); 

をサポートしていますACL。 node-aclでは、役割に権限を与えることで役割が作成されます。その一石二鳥のような

acl.allow('admin', ['/', '/forum', '/forum/threads'], '*'); 
acl.allow('public', ['/', '/forum', '/forum/threads'], 'show'); 
acl.allow('user', ['/', '/forum', '/forum/threads'], ['create', 'show']); 

は、新しいリソースがジョンによって作成されたと仮定します(何の鳥が実際に損をしている)、我々はジョンも更新し、そのリソースを削除することを可能にする新しいレコードを追加します。

acl.allow('john', ['/forum/threads/abc123'], ['update', 'delete']); 

私のアプリケーションもexpressを使用していますので、ルーティングミドルウェアのアプローチを使用してルートを確認します。私のルーティング設定では、私はほとんどの特急構成でライン

を追加することになり、これはパラメータが渡されていない場合req.userIdで定義された役割がある場合、これはチェックします

app.post('/', acl.middleware(), function(req, res, next) {...}); 
app.post('/forums', acl.middleware(), function(req, res, next) {...}); 
app.post('/forums/:forumId', acl.middleware(), function(req, res, next) {...}); 
app.post('/forums/threads', acl.middleware(), function(req, res, next) {...}); 
app.post('/forums/threads/:threadId', acl.middleware(), function(req, res, next) {...}); 

posのためのように見えます特定されたリソース上でhttpメソッドを実行することを許可されています。

この例では、httpメソッドはpostですが、設定でidenitifiedされた各httpに対して同じことが実行されます。

これにより、以前に定義されたアクセス許可に関する質問が発生します。これらの質問に答えるために、我々は

  • を作成

    • からパーミッションを変更しなければならない従来の

      • ポスト

      を破壊

    • 更新
    • を表示
    • は、この例では、ハードコードされたすべてのものを示しているが、より良い練習は、彼らが作成することができるので、自分の権限の管理インタフェースを持って読んで、更新することであり、なくても、動的に削除

    を削除

  • を入れますコードを変更します。

    私はnode-aclプラグインのアプローチが好きです。これは非常にまっすぐ前方で柔軟なAPIを使用してきわめてきめ細かな権限 - ロール割り当てを可能にするからです。彼らのドキュメンテーションにはもっとたくさんのものがあります。

    うまくいけば、これが役に立ちます。

  • +0

    公開されているものは何ですか?恥骨の資源を保護していない – danielad

    関連する問題