2017-05-27 10 views
0

Expressアプリケーション用のデータベースベースのACLの種類を構築しようとしています。データベースエントリへのExpressルートの照合

  • リソース:*
  • 方法:*
  • RoleID:1
  • isAllowed:true

私は現在、そのようなことが含まれているデータベースの権限テーブルを持っています
  • リソース:/users
  • 方法:GET
  • RoleID:2
  • isAllowed:false

  • リソース:/users/id/*
  • 方法:GET
  • RoleID:2
  • isAllowed:true

私の目的は、データベース内のルールに基づいてルートをリクエストオブジェクトにチェックし、許可または拒否したミドルウェアを構築することです。私の実際的な問題は、/users/id/1とデータベースエントリ/users/id/*をどのようにマッチさせるかです。私が正規表現の基礎としてデータベースエントリを使用する場合、/users/id/1は明らかに一致していますが、各要求に対してすべてのデータベースエントリを取得してテストすることは現実的ではないと思います。要求されたURLに基​​づいてデータベースから適切なルールを取得する最良の方法は何と思いますか?

ありがとうございました!

答えて

0

、(私はSequelizeを使用しています)、[OK]を思考と研究のビットの後、私はあなたがMySQLのクエリで正規表現を使用できることを発見したので、私は、このミドルウェアを作ってみた:

module.exports = function (req, res, next) { 
    // If a wildcard is in place, skip the rest 
    return models.Permissions.findAll({ 
    where: { 
     resource: '*', 
     GID: req.session.role, 
     isAllowed: 1 
    } 
    }).then(function (result) { 
    if (result[0]) { 
     return next() 
    } 

    // If the URL contains more than one element, replace the last item with [item, *] 
    // to match eventual wildcards in the database entries 
    let urlItems = req.url.split('/').filter(Boolean) 
    let url = req.url 
    if (urlItems.length > 1) { 
     let lastItem = '[' + urlItems[urlItems.length - 1] + ', *]' 
     url = req.url.split('/') 
     url[url.length - 1] = lastItem 
     url = url.join('/') 
    } 

    let query = 'SELECT * FROM Permissions ' 
    query += 'WHERE resource RLIKE "^' + url + '?$" ' 
    query += 'AND GID = ' + req.session.role 

    return models.sequelize.query(query, { 
     type: models.sequelize.QueryTypes.SELECT 
    }).then(function (result) { 
     let policy = result[0] 

     function return403() { 
     res.status(403).send('Forbidden') 
     } 

     // Forbid everything by default 
     if (!policy) { 
     return403() 
     return 
     } 

     let methods = policy.method.toUpperCase().split(' ') 

     // Forbid all methods which are not allowed 
     if (policy.method === '*' || methods.includes(req.method)) { 
     if (!policy.isAllowed) { 
      return403() 
      return 
     } 
     } 

     // When other methods are explicitly allowed, forbid everything else 
     if (policy.method !== '*' && !methods.includes(req.method) && policy.isAllowed) { 
     return403() 
     return 
     } 

     // Standard behaviour: allow explicitly allowed methods (or *) that are allowed. 
     next() 
    }) 
    }) 
} 
関連する問題