Javascript Passport.js在请求登录时失败

Javascript Passport.js在请求登录时失败,javascript,node.js,sails.js,passport.js,Javascript,Node.js,Sails.js,Passport.js,我已经在sails.js中配置了passport.js,并且正在使用passport ldapauth进行身份验证 我相信我已经正确地配置了它,LDAP返回了一个关于用户的一些参数,但是当我尝试req.logIn时,passport.js似乎死了 以下是AuthController的一部分: process: function (req, res) { passport.authenticate('ldapauth', {session: true}, function(err, use

我已经在sails.js中配置了passport.js,并且正在使用passport ldapauth进行身份验证

我相信我已经正确地配置了它,LDAP返回了一个关于用户的一些参数,但是当我尝试req.logIn时,passport.js似乎死了

以下是AuthController的一部分:

process: function (req, res) {
    passport.authenticate('ldapauth', {session: true}, function(err, user, info) {
      console.log("Authenticated?", err, user, info);

      if ((err) || (!user)) {
        res.redirect('/login');
        return;
      }

      req.logIn(user, function (err) {
        if (err) {
          console.log(err);
          res.view();
          return;
        }
        res.redirect('/');
        return;
      });
    })(req, res);
  },
以下是passport stategeies和serialize用户函数:

function findByEmployeeID(u, fn) {
  User.findOne({
    employeeID: u
  }).done(function (err, user) {
    // Error handling
    if (err) {
      return fn(null, null);
      // The User was found successfully!
    } else {
      return fn(null, user);
    }
  });
}

passport.serializeUser(function (user, done) {
  console.log("Serialize User", user.id);
  done(null, user.id);
});

passport.deserializeUser(function (id, done) {
  findById(id, function (err, user) {
    console.log("Deserialize User: ", id, user.id);
    done(err, user);
  });
});

passport.use(new LDAPStrategy({
    server: {
      url: 'ldap://server.domain.com:389',
      adminDn: '<ADMIN BIND DN>',
      adminPassword: '<ADMIN BIND PW>',
      searchBase: '<BASEDN>',
      searchFilter: '(&(objectClass=person)(sAMAccountName={{username}}))',
      searchAttributes: ['sAMAccountName', 'employeeID', 'mail', 'displayName', 'givenName', 'sn', 'telephoneNumber','mobile'],
    }
  }, function (user, done) {
    // Will always have an authenticated user if we get here since passport will indicate the failure upstream.

    console.log("LDAP User", user.employeeID); //This returns the proper users EmployeeID.

    //Map the LDAP user to our local mapping
    var mapUser = ldapUserMapping(user);

    //Check to see if the user exists in the local database
    findByEmployeeID(mapUser.employeeID, function (err, localUser) {
      if (err) done(err, null, err);
      if (!localUser) {
        //This must be a new user who authenticated via LDAP, create a local user account.
        User.create(mapUser).done(function(err, localUser){
          if (err) done(err, null, err);
          return done(null, localUser);
        });
      } else {
        //This is a user who has accessed our system before

        //Maybe update the user settings if upstream LDAP has updated anything.

        //Return User
        return done(null, localUser);
      }
    });
  }
));
Passport序列化程序调试:

Passport.prototype.serializeUser = function(fn, done) {
  if (typeof fn === 'function') {
    return this._serializers.push(fn);
  }

  // private implementation that traverses the chain of serializers, attempting
  // to serialize a user
  var user = fn;

  var stack = this._serializers;
  (function pass(i, err, obj) {
    console.log("Beginning pass with: ", i, err, obj);
    // serializers use 'pass' as an error to skip processing
    if ('pass' === err) {
      err = undefined;
    }
    // an error or serialized object was obtained, done
    if (err || obj || obj === 0) {
      console.log("ERROR Or OBJ obtained:", i, err, obj);
      return done(err, obj);
    }

    var layer = stack[i];
    if (!layer) {
      console.log("This failed to serialize?", i);
      return done(new Error('failed to serialize user into session'));
    }

    try {
      layer(user, function(e, o) {
        console.log("From serialize function", i, e, o);
        pass(i + 1, e, o);
        console.log("After Pass?: ", i, e, o);
      } )
    } catch(e) {
      console.log("On catch: ", i, e);
      return done(e);
    }
  })(0);
}
以下是更新的输出:

LDAP User abc123
Authenticated? null { username: 'abc123',
  employeeID: 'abc123',
  email: 'First_Last@domain.com',
  firstName: 'First',
  lastName: 'Last',
  createdAt: Wed Apr 30 2014 17:09:21 GMT-0400 (EDT),
  updatedAt: Wed Apr 30 2014 17:09:21 GMT-0400 (EDT),
  id: '53616681156b068d3b38f8cb' } undefined
req.login about to call passport serializeUser
Beginning pass with:  0 undefined undefined
Serialize User 53616681156b068d3b38f8cb
From serialize function 0 null 53616681156b068d3b38f8cb
Beginning pass with:  1 null 53616681156b068d3b38f8cb
ERROR Or OBJ obtained: 1 null 53616681156b068d3b38f8cb
On catch:  0 [TypeError: object is not a function]
debug: Lowering sails...


~/project/node_modules/sails-mongo/node_modules/mongodb/lib/mongodb/connection/base.js:245
        throw message;
              ^
TypeError: object is not a function
    at pass (~/project/node_modules/passport/lib/passport/index.js:293:14)
    at Passport.serializeUser (~/project/node_modules/passport/lib/passport/index.js:295:5)
    at IncomingMessage.req.login.req.logIn (~/project/node_modules/passport-ldapauth/node_modules/passport/lib/http/request.js:51:29)
    at ~/project/api/controllers/AuthController.js:34:11

它似乎无法序列化用户,尽管我不确定原因。SerializeUser应该传递user.id值,尽管它似乎不在passport.js中工作。可能我的配置不正确?

设置passport时,您是否完成了第一步

Before authenticating requests, the strategy (or strategies) used by an application must be configured. passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username, password: password }, function (err, user) { done(err, user); }); } )); 在验证请求之前,必须配置应用程序使用的策略。 passport.use(新本地策略)( 函数(用户名、密码、完成){ findOne({username:username,password:password},函数(err,User){ 完成(错误,用户); }); } ));
被调用的
代码应该遍历已注册的
序列化用户
函数并调用它们(
lib/authenticator.js
第275行)。调试日志表明该数组中没有函数。您似乎正确注册了serializeUser回调,这就是我倾向于出现初始化问题的原因。

我不确定为什么将此对象作为第二个参数传递给serializeUser,但这似乎就是问题所在

this._passport.instance.serializeUser(user, function(err, obj) {
//this._passport.instance.serializeUser(user, this, function(err, obj) {
在~/project/node_modules/passport ldapauth/node_modules/passport/lib/http/request.js文件中进行这些更改似乎可以解决问题


我不确定安装ldapauth模块时发生这种情况的确切原因。我将进一步调查。

看起来passport.js代码穿过了第0层,它的堆栈上有我的自定义seralizeUser函数。它尝试它,然后返回(null,user.id),然后在下一次迭代中调用pass。下一次迭代经过,发现它没有传递错误,传递了一个obj(user.id),然后返回done(err,obj)。这应该是成功的标志。然后在此之后调用catch并返回一个错误?似乎正在向this对象传递done。this.\u passport包含一个具有LDAP策略的实例,尽管_序列化程序和_反序列化程序似乎设置为null?虽然它似乎仍然调用我的serialize函数。我替换了://this.\u passport.instance.serializeUser(用户,this,函数(err,obj){this.\u passport.instance.serializeUser(用户,函数(err,obj){我添加了更多的调试和额外的代码块。似乎每个签名都在正常执行。passport代码接收到一个序列化的用户id,然后尝试通过一个额外的过程并实现它并返回,但是catch块仍然错误?我不确定尝试设置它时出错了什么。我重新开始d遵循了这个指南,然后添加了ldap身份验证,现在一切似乎都好了。
this._passport.instance.serializeUser(user, function(err, obj) {
//this._passport.instance.serializeUser(user, this, function(err, obj) {