我有以下代码,每次输入0.0.0.0:3000/user?apikey=xxx
时,本地策略中的代码都不会运行,而是直接进入“未授权”页面。我试图从server.get('/user')
删除passport.authenticate。在调试模式下,我可以看到'apikey'被解析出来请求参数映射。所以这里的问题是护照无法验证获取请求。任何帮助将不胜感激。谢谢!
var restify = require('restify');
// Create server
var server = restify.createServer({
name: 'server'
});
server.use(restify.queryParser());
server.use(restify.bodyParser());
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function (apikey, done) {
console.log('Entered authentication.');
done(null, null);
}
));
//specify route
server.get('/user', passport.authenticate('local'), function (req, res) {
console.log(req.params);
res.end('haha');
});
server.listen(3000, function () {
console.log('%s listening at %s', server.name, server.url)
});
答案 0 :(得分:4)
LocalStrategy用于通过用户名和密码验证用户身份。传递的函数需要3个参数:用户名,密码和完成的回调。你的功能只需要两个apikey就完成了。
此策略不适合您,因为它通过请求中发布的凭据(即登录页面)对用户进行身份验证,这在您使用会话时很有用。另一方面,您必须通过URL中的apikey字符串验证每个GET请求。所以你应该编写一个中间件来验证它。
server.use(function(req,res,next){
key=req.query['apikey']; //get key from url
//authenticate it
if(valid(key))
next();
else
res.redirect('/unauthorized');
});
在路由器之前使用此功能。
答案 1 :(得分:0)
另一种方法是简单地使用HTTP BASIC身份验证。这样,用户ID /密码在授权头中发送,而不是URI的一部分,因为这是保护服务的一种相当常见的方法(只需确保通过HTTPS执行此操作)。我写了这个小小的模块来完成从passport-http的一些例子中借用的部分内容。
var restify = require('restify'),
userId = process.env.serviceID,
pwd = process.env.servicePassword,
passport = require('passport'),
BasicStrategy = require('passport-http').BasicStrategy;
passport.use(new BasicStrategy(
function (username, password, done) {
findByUsername(username, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (user.password !== password) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
var users = [
{ id: 1, username: userId, password: pwd}
];
function findByUsername(username, fn) {
for (var i = 0, len = users.length; i < len; i++) {
var user = users[i];
if (user.username === username) {
return fn(null, user);
}
}
return fn(null, null);
}
exports.authenticate = function (req, res, next, callback) {
passport.authenticate('basic', function (err, user) {
if (err) {
console.log(err);
return next(err);
}
if (!user) {
var error = new restify.InvalidCredentialsError("Failed to authenticate to ma-services.");
console.log(error);
res.send(error);
return next();
}
callback(req, res, next);
})(req, res, next);
};
要调用它,我只需从服务器将调用的导出API调用执行以下操作:
var basicAuth = require(__dirname + '/../utils/authn.js');
exports.count = function (req, res, next) {
basicAuth.authenticate(req, res, next, function() {
validateParam(req.params.uid, next);
var url = '/count/' + encodeURIComponent(req.params.uid);
processRequest(req, res, next, url);
});
};