restify.js + passport.js没有验证GET请求

时间:2013-08-26 03:26:15

标签: node.js restify passport.js

我有以下代码,每次输入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)
});

2 个答案:

答案 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);
    });
};