使用 Passport.js 部分保护 API 端点
Posted
技术标签:
【中文标题】使用 Passport.js 部分保护 API 端点【英文标题】:Partially protect API endpoint with Passport.js 【发布时间】:2015-08-07 10:42:18 【问题描述】:根据用户登录状态,我想从 SAME api 端点提供不同的结果。
用例是从相同的 api 端点提供文章。 所以有些文章是公开的,而有些是私人的。 还有专门的页面,可以查询文章列表。
示例: api/articles/special/all
此 API 应返回数据库中当前的所有页面。 但如果用户未登录,它也应该过滤掉私人结果。
使用 Passport.js 我只能保护整个 API 端点,例如:
router.get('/', auth.isAuthenticated(), controller.index);
虽然我想在实际函数中调用 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);
);
;
任何想法,如何在控制器内使用 Passport.js,而不是保护整个 API 端点?
【问题讨论】:
【参考方案1】:我不确定如何使用 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);
因为 Stormpath 为您存储用户,如果您使用 express-stormpath 库,这意味着它将尝试通过网络会话(在浏览器中)或用户的 API 密钥(Stormpath 也商店)。
这就是它工作起来非常简单的原因,因为中间件将检查传入的 HTTP 标头并使用 Basic Auth 或 OAuth2 正确验证用户 =)
【讨论】:
以上是关于使用 Passport.js 部分保护 API 端点的主要内容,如果未能解决你的问题,请参考以下文章
Express + Passport.js:req.user 未定义
使用 passport.js、sails.js API 和 ember.js 登录 Facebook