Passport身份验证系统无法运行

时间:2017-05-06 02:24:53

标签: node.js express passport.js

我的快递节点应用程序中有一个身份验证系统设置,但我在设置的护照身份验证时遇到了一些错误。例如,注册系统工作正常,我的验证系统(基本上检查用户/通行证组合是否对我学校的成绩簿登录有效)。但是,实际的护照登录(检查用户/通行证组合是否是我的mongoose数据库中的注册用户)无法正常运行。

  

关联 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);
  

最后, 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

  

更新:   因此,通过最新的建议,我得到以下输出:enter image description here因此登录正在运行。然而,问题是,登录似乎是循环并识别用户一次,然后显示"无效登录"消息,而不仅仅是完成过程

2 个答案:

答案 0 :(得分:2)

我发现了2个问题。

首先:

在app.js文件中,配置 LocalStrategy 后,您必须在检查用户凭据后调用 done

请参阅:

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.)');
            }
        });
    });
}));

二:

在您的登录路由配置中,您已经处理了调用 next 函数的错误,并且错误处理函数将捕获它。

//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) {
    ...

检查this以获取有关中间件的更多示例。

希望现在很清楚。

答案 1 :(得分:0)

问题是验证完成后您缺少verify callback。请尝试以下代码:

在下面的代码中,当你创建一个LocalStrategy时,你在函数中有三个参数,即用户名,密码和完成。现在,当您的if (userIsValid)有效时,您需要调用done(null, user)的验证回调。因此,您可以在使用user进行身份验证时获得passport.authenticate

    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
});