Passport本地策略 - 单页应用程序的自定义回调

时间:2016-04-09 19:35:03

标签: node.js express passport.js passport-local

我是Node的新手,我正在建立一个单页网页应用。我正在使用Express和Mongoose,试图像these docs.那样设置一个登录电话。我可能已经完全弄错了这么棒的道路。

首先,我正在收听登录帖子。这是我想在响应中添加自定义数据的位置,具体取决于它是否经过身份验证。 The documentation我提到 list.setSelection(3) 已作为参数传入,但我认为无法访问它。另外,第一个参数应该是" res" (通常为空)?我承诺进一步向下的err声明需要致电.catch,否则请求无法完成。

done()

护照设置:

app.post('/login',passport.authenticate('local-signin', 
    function(req, res) {
        // wasn't sure what I should be doing here
    }
  ));

验证处理程序:

passport.use('local-signin', new LocalStrategy(
{passReqToCallback : true}, 
  function(req, username, password, done) {
    funct.localAuth(username, password)
    .then(function (user) {
      if (user) {
        console.log("LOGGED IN AS: " + user.username);
        done(null, user);
      }
      if (!user) {
        done(null, false);
      }
    })
    .catch(function (err){
      console.error(err.message);
      done(err);
    });
  }
));

1 个答案:

答案 0 :(得分:0)

同样,我认为您面临的主要问题是:

 funct.localAuth(username, password)
.then(function (user) {

return db.User.findOne({ username: username }).exec()
.then(function (result){

问题是Node在有机会返回之前就已经开始了。在此之后注销一些内容,您会在findOne解析用户之前看到它已被记录。

function logUser() {
  db.User.findOne({ username: username }).exec()
    .then(function (user) {

      console.log('this will log second', user)
    })

  console.log('this will log first')
}

这是我在项目中基本上设置护照的方式:

  

AUTH / index.js

passport.use(new LocalStrategy({ passReqToCallback : true }, function (req, username, password, done) {

  db.User.findOne({ username: username }).exec()
    .then(function (user) {

      // It's a security thing to not let the user (potential hacker) to know whether a user exists
      // in the system or not, or if the email was wrong, or just the password, send them a generic error.
      if (!user)
        return done('Could not log you in with that email and password combination.', false)

      account.validatePassword(password)
        .then(function (result) {
          console.log(result) // The bcrypt result
          done(null, user)
        }, function (err) {
          console.error('Could not validate password', err)
          done(err, false)
        })

    }, function (err) {
        console.error('Could not find user', err)
    })

}))


module.exports = passport

现在您可以在其他地方使用auth模块(例如中间件)以及添加其他策略(例如承载)。

  

模型/ user.js的

userSchema.methods.validatePassword = function (password) {
  var user = this

  // This is how you properly return a promise.
  // Notice I'm either resolving or rejecting, not returning the result inside the function (I'm only using `return` so it exits the function early.)
  return new Promise(function (resolve, reject) {
    bcrypt.compare(password, user.passwordHash, function (err, result) {
      if (err)
        return reject(err)

      if (!result)
        return reject('Could not log you in with that email and password combination.')

      resolve(result)
    })
  })
}
  

中间件/本地auth.js

var passport = require('../auth')

module.exports = passport.authenticate('local-auth')
  

路由器/路由/ users.js

var localAuth = require('../../middleware/local-auth')

router.post('/login', localAuth, login)
// Other routes...

return router


function login(req, res) {
  // You have have a req.user
  res.send(req.user)
}
  

router / index.js(这可能有点落伍,但我想提供一个真实的解决方案)

module.exports = function (app) {
  app.use('/api/users', require('./routes/users'))
  // Other endpoints...
}
  

server.js

require('./middleware/express')(app)
require('./router')(app)

至于done()业务:

done()回调有两个参数:错误,即用户。 在Passport的某个地方,它接收您使用以下语法传递的参数:

function (err, user) { }

这是社区采用的Node.js标准,用于为回调带来订单,因为在承诺或生成器之前,回调是"事情"人们有时把它作为最后一个参数,甚至是中间的某个地方。它现在总是第一个。你可能会看到它被称为next(),它也是一样的。如果需要,可将其更改为next()moveItAlong(),它将像以前一样执行。只需在代码中使用next(),以便对其他人有意义。

因此,当你传递done(null, user)时,它只是意味着没有错误,而在Passport中,当回调处理程序检查错误时,没有任何错误,它继续进行。如果你没有调用回调(done()),那么没有任何反应。 Passport永远不会收到错误或用户,因为您从未调用过回调;这就是您需要在done()中调用.catch()的原因。