2

我有以下代码,每次输入时0.0.0.0:3000/user?apikey=xxx,本地策略中的代码都不会运行,它会直接进入“未经授权”页面。我试图从中删除 passport.authenticate server.get('/user')。在调试模式下,我可以看到“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)
});
4

2 回答 2

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');
});

在路由器之前使用它。

于 2013-08-26T06:57:05.927 回答
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);
    });
};
于 2014-11-04T19:50:38.970 回答