2016-11-24 4 views
0

私はループバックで3つのモデルを持っているとしましょう:リーダー、ブック、ノート。 。Readerは、ユーザーのインスタンスであるとのかかわりにログインすることができますすることは、そのようなものです:ループバックのアクセス制御はフィルタを含む

  • Readerは、多くの本を持っている
  • Readerは、多くのノートを持ってい
  • ブックは
  • 注リーダー
  • に属し、多くのノートを持っていますノート

私が達成しようとしているのは、ログインしたリーダーのすべての書籍に、書籍とリーダー。

APIコールは、次のようになります。

/api/reader/me/books?filter[include]=notes 

しかし、彼らはリーダーに属している場合、これは関係なく、ブックに属するすべての内容を返します。私は別のフィルタをAPIコールに追加することができますが、リーダが他の読者のメモにアクセスできないように、サーバ側のノートをフィルタリングする必要があります。

私はブックモデルにこのアクセスコントロールを追加しようとしました

{ 
    "principalType": "ROLE", 
    "principalId": "$owner", 
    "permission": "ALLOW", 
    "property": "__get__notes" 
} 

とモデル

[ 
    { 
     "principalType": "ROLE", 
     "principalId": "$everyone", 
     "permission": "DENY" 
    }, { 
     "principalType": "ROLE", 
     "principalId": "$owner", 
     "permission": "ALLOW", 
     "property": "*" 
    } 
] 

を注意するために、このACLそれはこの

/api/reader/me/books/<bookId>/notes 
などの呼び出しに適しています

が含まれていますが、最初の呼び出しではincludeフィルタは使用されません。書籍に読者のメモを埋め込むためにはどうすればよいですか?

ご迷惑をおかけして申し訳ございません。

+0

SLで使用されているモデルごとのベースではなく、インスタンス単位でアクセスを制限または許可する必要がある同様の問題がありました。残念ながら、これを行う適切な方法が見つからず、自分の認証レイヤーを実装する必要がありました。しかし、あなたができることの1つは、afterRemoteフックの単純なフィルタリングです。そうすれば、あなたはアクセス可能なインスタンスだけを返すように何らかの種類の減算を行うことができます。私の場合、これは不可能でした。なぜなら、ユーザーAのインスタンスにユーザーBがアクセスできる必要があったからです。これはあなたのケースではないので、うまくいく可能性があります。 – Acapulco

+0

ここでドキュメントを読むことができます - https://loopback.io/doc/en/lb2/Remote-hooks.html - それはまっすぐではなく、あまり効率的ではありません – Acapulco

答えて

0

これを実現するには、リモートメソッドを作成する必要があります。アプリケーションレベルでフィルタを適用する必要があります。

は、ユーザーの詳細は、今、あなたは他のすべてのメソッドを制限し、単にこのリモートメソッドを許可することができUserモデル

module.exports = function(Reader){ 

    var async = require('async'); 
    Reader.fetchBooks = function(userId, callback){ 
     var app = this.app; 
     var updatedReaderList = []; 
     Reader.find({ 
      where: {userId: userId }, 
      include: {relation: "books"} 
     }, function(err, readerList){ 
      if(err){ 
       return callback(err); 
      } 
      if(readerList){ 
       if(readerList.length){ 
        var series = []; 
        readerList.forEach(function(reader){ 
         var readerObj = reader.toJSON(); 
         updatedReaderList.push(readerObj); 
         if(readerObj.books){ 
          readerObj.books.forEach(function(book){ 
           series.push(function(callback){ 
           fetchNotes(app, book, readerObj.id, callback); 
           }); 
          } 
         } 
        }); 

        //Now save the data in series.. 
        async.series(series, function(err){ 
         if(err){ 
          callback(err); 
         }else{ 

          //Now send the callback 
          callback(null, updatedReaderList); 
         } 
        }); 

       }else{ 
        callback(null, []) 
       } 
      }else{ 
       callback(null, []) 
      } 
     }); 


    }; 

    var fetchNotes = function(app, book, readerId, callback){ 
     var Note = app.models.Note; 
     //Fetch only those note whose reader id belongs to current reader and book belongs to same one. 
     Note.find({ 
      where: { 
      readerId: readerId, 
      bookId: book.id 
      } 
     }, function(err, noteList){ 
      if(err){ 
      return callback(err); 
      }else{ 
      if(noteList){ 
       book.notes = noteList; 
      } 
      } 
     }); 
    }; 
} 

に店であると仮定します。

{ 
    "principalType": "ROLE", 
    "principalId": "$owner", 
    "permission": "ALLOW", 
    "property": "fetchBooks" 
} 

注:約束を使用してコールバックhellを削除できます。

関連する問題