我是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);
});
}
));
答案 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()
的原因。