通过Passport.js部分保护API端点

arc*_*col 6 authentication node.js passport.js

根据用户登录状态,我想从SAME api端点提供不同的结果。

用例具有从相同api端点提供的文章。因此,有些文章是公开的,而有些则是私人的。还有一些特殊页面,可以在其中查询文章列表。

示例:api / articles / special / all

此API应该返回数据库中当前的所有页面。但是,如果用户未登录,它还应该过滤掉私有结果。

使用Passport.js,我只能保护整个API端点,例如:

router.get('/', auth.isAuthenticated(), controller.index);
Run Code Online (Sandbox Code Playgroud)

虽然我想从实际函数中调用auth.isAuthenticated()方法,例如:

// Get list of articles
exports.index = function(req, res) {
  Article.find(function (err, articles) {
    if(err) { return handleError(res, err); }
    var titles = [];
    var loggedIn = false;
    if (auth.isAuthenticated()) {loggedIn = true;} // NOT WORKING
    for (var i = 0; i<articles.length; ++i) {
      if (articles[i].role === 'loggedIn' && loggedIn) {
          titles.push(articles[i].name);
      } else if(articles[i].role !== 'loggedIn') {
        titles.push(articles[i].name);
      }
    }
    return res.json(200, titles);
  });
};
Run Code Online (Sandbox Code Playgroud)

任何想法,如何从控制器内部使用Passport.js,而不是保护整个API端点?

rde*_*ges 0

我不确定如何使用 Passport.js 来完成此任务,但如果您使用Stormpath之类的东西,那么开箱即用即可轻松完成此任务。

一旦您初始化/配置了express-stormpath中间件,它将自动尝试对任何用户进行身份验证,而无需您显式使用中间件。

例如,你可以说:

var express = require('express');
var stormpath = require('express-stormpath');

var app = express();

app.use(stormpath.init(app));

app.get('/myapi', function(req, res) {
  if (req.user) {
    res.json({ status: 'YOU ARE LOGGED IN: ' + req.user.email });
  } else {
    res.json({ status: 'YOU ARE NOT LOGGED IN!' });
  }
});

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

因为 Stormpath 会为您存储用户,所以如果您使用的是express-stormpath 库,这意味着它将尝试通过 Web 会话(在浏览器中)或用户的 API 密钥(Stormpath 也存储)对用户进行身份验证。

这就是为什么它的工作非常简单,因为中间件将检查传入的 HTTP 标头并使用 Basic Auth 或 OAuth2 对用户进行正确的身份验证 =)