我想验证用户是否具有允许他/她在我的API中使用端点的角色。通常我会通过将userId作为JWT的一部分发送来执行此操作,并在DB上查找以查看用户的角色。它会发生在API调用中,看起来像这样:
var userId = getUserIdFromJwt();
app.models.User.findOne({_id: userId}, function (err, user) {
...check if user is in role...
});
现在我想尝试将代码移动到一个中间件,看起来像这样:
exports.isUserInRole = function(app, allowableRoles) {
var userId = getUserIdFromJwt();
app.models.User.findOne({_id: userId}, function (error, user) {
if (error) {
return res.status(500).json(error);
}
return function (req, res, next) {
if(_.includes(allowableRoles, user.Role)) {
next();
} else {
return res.status(401).json({"error": "User not in role"});
}
}
});
};
中间件将实现如下:
const allowableRoles = ['admin', 'implementor'];
app.get('/getStuff/', isUserInRole(app, allowableRoles), function (req, res) {
... do stuff if user is in role ...
});
此时我遇到app.models.User
值始终为undefined
的问题。
我不明白为什么此时app.models.User
未定义,因为我可以在get调用中的匿名函数中访问它。
如果我无法发送app.models.User
,我将如何从中间件访问数据库?
作为参考,我使用Mongoose并将其公开给我在server.js中的应用程序,我从中访问MongoDB数据库。
答案 0 :(得分:0)
我的第一个猜测是b / c你实际上是在调用函数而不是仅仅传入函数。另外,你实际上并没有传递中间件。中间件功能看起来像
function(req,res,next){}
此外,您可能希望利用会话而不是在每个请求上访问数据库
答案 1 :(得分:0)
我认为你的问题是你在实际初始化模型之前尝试获取模型,因为你将应用程序绑定到应用程序初始化时的参数。
因此,在您的主应用文件中,我会module.exports = app;
,然后在您的中间件文件中,只需通过执行var app = require('./path/to/app');
来包含该应用。然后从中间件中删除app
。你最终会得到这样的东西:
var app = require('./path/to/app');
exports.isUserInRole = function(allowableRoles) {};
在您的路线中将其更改为:
const allowableRoles = ['admin', 'implementor'];
app.get('/getStuff/', isUserInRole(allowableRoles), function (req, res) {}
最后在您的应用文件中,将应用添加到导出中:
module.exports = app;
编辑:
如果你使用的是Mongoose,你也可以做一些更简单的事情:
var mongoose = require('mongoose');
var User = mongoose.model('User');