我收到来自 Node.js、Restify 和 Passport 的 401 Unauthorized

I am getting a 401 Unauthorized from Node.js, Restify and Passport

尽管我的所有控制台日志都在打印,但我收到了 401...

这是我的服务器代码:

var Datastore = require('nedb');
var db = new Datastore({
        filename : 'datafile.db',
        autoload : true
    });

var restify = require('restify');
var passport = require('passport');
var LocalStrategy = require("passport-local").Strategy;
var sessions = require("client-sessions");
var morgan = require('morgan');

var server = restify.createServer();

server.use(sessions({cookieName : 'session', secret : 'mycoolsecret', duration : 5 * 24 * 60 * 60 * 1000}));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(passport.initialize());
server.use(passport.session());
server.use(morgan('dev'));

passport.serializeUser(function (user, done) {
    console.log("serializeUser: " + JSON.stringify(user));
    done(null, user._id);
});

passport.deserializeUser(function (id, done) {
    console.log("deserializeUser: " + id);
    db.findOne({
        _id : id
    }, function (err, doc) {
        if (doc) {
            return done(null, doc); // TODO: remove pwd hash
        }
    });
});

var lookupUser = function (Username, Password, done) {
    // TODO: check pwd hash
    db.findOne({
        Username : Username
    }, function (err, doc) {
        if (err) {
            console.log(err);
        }
        console.log("doc: " + doc.Username);
        if (doc) {
            return done(null, doc);
        } else {
            console.log("no user found for: " + Username);
        }
    });
    return done(null, false, {
        error : 'Incorrect username or password.'
    });
};

passport.use(new LocalStrategy({
        usernameField : 'Username',
        passwordField : 'Password',
        session : true
    }, lookupUser));

// TODO: check for collisions
// TODO: hash pwd with bycrypt
server.post('/api/signup', function (req, res) {
    db.insert({
        Username : req.body.Username,
        Name : req.body.Name,
        Password : req.body.Password,
        Email : req.body.Email
    }, function (err, newDoc) {
        if (err)
            res.json(500, {
                msg : err
            });
        else
            res.json({
                msg : 'OK'
            });
    });
});

server.post('/api/login', passport.authenticate('local'), function (req, res) {
    console.log('this is printing, but it still fails: ', req.user);
    res.send(200, {msg : 'OK'});
});

server.listen(8080, function () {
    console.log('%s listening at %s', server.name, server.url);
});

下面是package.json中的依赖:

  "dependencies": {
    "restify": "~2.8.4",
    "passport": "^0.2.1",
    "passport-local": "^1.0.0",
    "client-sessions": "^0.7.0",
    "nedb": "^1.1.1",
    "morgan": "^1.5.1"
  },

这是我的注册测试代码:

var restify = require('restify');
var assert = require('assert');

// init the test client
var client = restify.createJsonClient({
  url: 'http://localhost:8080',
  version: '*'
});

client.post('/api/signup', { Name: "John Smith", Email: "john@smith.com", Password: "pwd", Username: "john"},
    function(err, req, res, data) {                
        if (err) {
            throw new Error(err);
        } else {
            console.log(data.username);
            client.close();
        }
    }
);

console.log("test_signup");

下面是触发 401 的测试代码:

var restify = require('restify');
var assert = require('assert');

// init the test client
var client = restify.createJsonClient({
        url : 'http://localhost:8080',
        version : '*'
    });

client.post('/api/login', {
    Password : "pwd",
    Username : "john"
},
    function (err, req, res, data) {
    if (err) {
        throw new Error(err);
    } else {
        console.log(data.Username);
        client.close();
    }
});
console.log("test_login");

这是服务器的输出:

POST /api/login 401 1.652 ms - - doc: john serializeUser:
{"Username":"john","Name":"John
Smith","Password":"pwd","Email":"john@smith.com","_id":"0drs1nALTwidhQMD"}
this is printing, but it still fails:  { Username: 'john',   Name:
'John Smith',   Password: 'pwd',   Email: 'john@smith.com',   _id:
'0drs1nALTwidhQMD' }

找到了...

这段代码总是被执行:

return done(null, false, {
    error : 'Incorrect username or password.'
});

将代码移至 if (doc) 的 else 分支可解决问题。