2017-05-06 166 views
1

我在我的express节点应用程序中安装了身份验证系统,但我在设置护照身份验证时遇到了一些错误。例如,注册系统工作正常,我的验证系统(基本上检查用户/传球组合是否对我学校的成绩簿登录有效)也可以正常工作。但是,实际的护照登录(它检查用户/传递组合是否是我的猫鼬数据库中的注册用户)无法正常工作。护照身份验证系统不工作

Relavent part of app.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); 

and finally, 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; 

所有帮助表示赞赏。如果更容易处理,源代码可以发现 here

UPDATE: So with the latest suggestions, I get the following output: enter image description here And thus the login is functioning. However, the thing is, the login seems to be looping and recognizing the user once, then showing the "invalid login" message rather than just finishing the process

回答

2

我发现了2个问题。

第一:

在app.js文件,您可以配置LocalStrategy之后,你必须调用您检查用户凭据后。

参见:

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 
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),它是中间件的参数。

所以你打电话给/登录路线,你有请求和回应,接下来,你拨打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) { 
    ... 

检查this了约中间件更多的例子。

希望现在很清楚。

+0

这并没有为我 – Markoe7

+0

你可以把更多的细节有关错误的工作? –

+0

我只是没有输出 – Markoe7

0

问题是验证完成后,您缺少一个verify callback。请尝试下面的代码:

在下面的代码中,当你创建一个LocalStrategy时,你在函数中有三个参数,即username,password和done。现在,当您的​​有效时,您需要调用验证回调,即done(null, user)。因此,使用passport.authenticate进行验证时,您可以获得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中的参数是从上面验证回调传递的参数。所以,你需要有在这种情况下,下面只有两个回调参数:

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

你是什么意思两个回调? – Markoe7

+0

回调中没有两个参数! – Tolsee

+0

对不起,我不确定我是否理解你在说什么 – Markoe7