web-dev-qa-db-ja.com

Passport.jsのアクセス/グループを確認する

Passport.jsを使用して、ユーザーが特定のエンドポイントにアクセスしたときに、正しいパスワードを持っているだけでなく、特定のグループのメンバーであるか、特定のアクセス権があることを確認したいと思います。

簡単にするために、USERとADMINのアクセスレベルがある場合。

パスポートを使用してパスワードを認証できます。

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

次に、ルートを使用して、ユーザーが認証を通過することを確認できます。

app.get('/api/users',
  passport.authenticate('local'),
  function(req, res) {
    res.json({ ... });
  });

しかし、/ api/users 'にアクセスするにはADMINアクセスが必要であるとしましょう。自分の戦略を書く必要がありますか? IE local-userおよびlocal-admin戦略が必要であり、それぞれに適切なアクセスレベルを確認しますか?

私はこれをかなり簡単に行うことができると思いますが、サイトに異なる認証方法(たまにoauthを使用することがある)が必要な場合に問題が発生し、それぞれにカスタムの* -user、*-admin戦略を作成する必要があります。やり過ぎのようです。

その他のオプションは、ユーザーが認証された後、各ルートのアクセス/グループを確認することです。しかし、できればミドルウェアでこれを実行したいと思います。

ありがとう

30

グループをチェックする単純なミドルウェアを作成できます。

var needsGroup = function(group) {
  return function(req, res, next) {
    if (req.user && req.user.group === group)
      next();
    else
      res.send(401, 'Unauthorized');
  };
};

app.get('/api/users', 
  passport.authenticate('local'),
  needsGroup('admin'), 
  function(req, res) {
    ...
  });

これは、オブジェクトがreq.userにはgroupプロパティがあります。このオブジェクトは、戦略の実装とdeserializeUserから渡されたオブジェクトです。

別の方法として connect-roles を使用することもできますが、Passportとどの程度統合できるかはわかりません。

EDIT:Passportとグループチェックミドルウェアを組み合わせることもできます。

var needsGroup = function(group) {
  return [
    passport.authenticate('local'),
    function(req, res, next) {
      if (req.user && req.user.group === group)
        next();
      else
        res.send(401, 'Unauthorized');
    }
  ];
};

app.get('/api/users', needsGroup('admin'), function(req, res) {
});
54
robertklep