Passport身份validation系统不工作

我有一个身份validation系统安装在我的快递节点应用程序,但我已经遇到了一些与我设置的护照authentication错误。 例如,注册系统工作正常,我的validation系统(基本上检查用户/通过组合对我学校的成绩簿login是否有效)也能正常工作。 但是,实际的护照login(它检查用户/传递组合是否是我的mongoose数据库中的注册用户)不能正常工作。

closuresapp.js的一部分

//passport setup app.use(passport.initialize()); app.use(passport.session()); passport.use(new LocalStrategy(function (username, password, done) { User.findOne({username: username}, function (err, user) { user.checkLogin(password, function (error, userIsValid) { if (error) { console.log('Error:'); return done(error); } if (userIsValid) { console.log('Valid:'); } }); }); })); 

user.js的

  var mongoose = require('mongoose'); var passportLocalMongoose = require('passport-local-mongoose'); var Schema = mongoose.Schema; var bcrypt = require('bcrypt'); var User = new Schema({ username: String, password: String, studentID: {type: Number} }); User.methods.checkLogin = function (password, callback) { bcrypt.compare(password, this.password, function (error, same) { if (error){ callback(error); } callback(same); }) }; User.plugin(passportLocalMongoose); module.exports = mongoose.model('User', User); 

最后是index.js

 var express = require('express'); var router = express.Router(); var passport = require('passport'); var User = require('../models/user'); var request = require('request'); var cheerio = require('cheerio'); //register router.post('/register', function(req, res){ var username = req.body.username; var password = req.body.password; var studentID = req.body.studentID; areCredentialsValid(username, password, function (statusBoolean) { if (statusBoolean === true){ User.register(new User({ username: username, password: password, studentID: studentID }), password, function (){ console.log('Registered:'); res.redirect('./'); res.end() }) }else{ console.log('Invalid Credentials:'); res.redirect('./'); res.end() } }); }); function areCredentialsValid(username, password, callback){ if (typeof username !== 'undefined' && username !== null && username !== '' && typeof password !== 'undefined' && password !== null && password !== ''){ var cookie = {}; var responseBoolean = false; var config = { method: 'GET', url: 'https://parents.mtsd.k12.nj.us/genesis/j_security_check', headers: { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36' } }; request(config, function (error, response, body) { cookie = response.headers['set-cookie']; console.log(cookie); var config = { method: 'POST', url: 'https://parents.mtsd.k12.nj.us/genesis/j_security_check', form: { 'j_username': username, 'j_password': password }, headers: { 'Cookie': cookie, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36' } }; request(config, function (error, response2, body) { //console.log(response); console.log(response2.headers); if (response2.headers['location'] === '/genesis/parents?gohome=true'){ responseBoolean = true; }else{ responseBoolean = false; } callback(responseBoolean); return responseBoolean; }) }) } } //login router.post('/login', function(req, res) { passport.authenticate('local', function (error, user, info){ if (user === false) { // handle login error ... console.log('failure'); } else { // handle successful login ... console.log('success'); } }); }); module.exports = router; 

所有的帮助表示赞赏。 如果更容易处理,可以在这里find源代码。

更新:所以最新的build议,我得到了以下输出: 在这里输入图像说明 因此loginfunction正常。 但是,事情是,login似乎是循环和识别用户一次,然后显示“无效login”消息,而不是只是完成过程

我发现了2个问题。

第一:

在app.js文件中,在configurationLocalStrategy之后 ,必须在检查用户凭据后调用完成

看到:

 passport.use(new LocalStrategy(function (username, password, done) { User.findOne({username: username}, function (err, user) { user.checkLogin(password, function (error, userIsValid) { // You function should return the user data, not just if it is valid or not. if (error) { console.log('Error:'); return done(error); } if (userIsValid) { console.log('Valid:'); // call done here return done(null, {_id: 123 /* data to represent the user*/}); } else { // call done here when the user is not valid console.log('Not Valid:'); return done(null, null, 'Invalid credentials (or something like this.)'); } }); }); })); 

二:

在你的login路由configuration中,你要处理调用下一个函数的错误,而你的error handling函数会捕获它。

 //login router.post('/login', function(req, res, next) { passport.authenticate('local', function (error, user, info){ if (user === false) { // handle login error ... next(new Error('AuthenticationError'), req, res); } else { // handle successful login ... res.redirect('/') } })(req, res, next); }); 

编辑最后的评论:

你不仅要检查用户是否是false ,而且也没有错误,请看:

 //login router.post('/login', function(req, res, next) { passport.authenticate('local', function (error, user, info){ // A error also means, an unsuccessful login attempt if(error) { console.error(error); console.log('Failed login:'); // And do whatever you want here. return next(new Error('AuthenticationError'), req, res); } if (user === false) { // handle login error ... console.log('Failed login:'); return next(new Error('AuthenticationError'), req, res); } else { // handle successful login ... console.log('Successful login:'); res.redirect('./'); } })(req, res, next); }); 

这在我这里工作。

关于(req, res, next) ,这是中间件的参数。

所以你打电话给/login路线,你有请求和响应,接下来,你调用passport.authenticate 。 这个方法返回一个function(req, res, next) ,最后传递请求和响应。

看到从passport.authenticate剪下的代码:

 module.exports = function authenticate(passport, name, options, callback) { ... // This is the function you call, when you do: (req, res, next) return function authenticate(req, res, next) { ... 

查看更多关于中间件的例子。

希望现在清楚。

问题是validation完成后,你缺less一个verify callback 。 请尝试下面的代码:

在下面的代码中,当你创build一个LocalStrategy时,你有三个参数,即用户名,密码和完成。 现在当你的if (userIsValid)有效时,你需要调用已done(null, user)validationcallbackdone(null, user) 。 所以,你可以通过使用passport.authenticate身份validation来获取user

  passport.use(new LocalStrategy(function (username, password, done) { User.findOne({username: username}, function (err, user) { user.checkLogin(password, function (error, userIsValid) { if (error) { console.log('Error:'); return done(error); } if (userIsValid) { console.log('Valid:'); //Below is the code you are missing return done(null, user) } }); }); })); 

passport.authenticate中的参数是从上面传递的validationcallback。 所以,在这种情况下,您将需要在callback中只有两个参数,如下所示:

 passport.authenticate('local', function (error, user){ //your-code });