【问题标题】:Passport Authentication System Not Working护照认证系统不工作
【发布时间】:2017-05-06 02:24:53
【问题描述】:

我在我的 express 节点应用程序中设置了身份验证系统,但我在设置的护照身份验证中遇到了一些错误。例如,注册系统和我的验证系统(它基本上检查用户/通行证组合是否对我学校的成绩册登录有效)工作正常。但是,实际的护照登录(检查用户/密码组合是否是我的 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.

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

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    我发现了 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 了解有关中间件的更多示例。

    希望现在很清楚。

    【讨论】:

    • 我只是没有输出
    • 我改了答案,看看吧!我相信现在是正确的。
    • 这似乎是我所需要的。只是有一个小问题(我在我的问题中更新了)
    • 原来的问题解决了吧?嗯...但是好的。你把代码push到github了吗??
    • 原来的问题似乎已经解决了,只是需要一些微调才能正常运行(然后你会收到赏金)
    【解决方案2】:

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

    在下面的代码中,当您创建 LocalStrategy 时,函数中有三个参数,即用户名、密码和完成。现在,当您的if (userIsValid) 有效时,您需要调用验证回调,即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
    });
    

    【讨论】:

    • 两次回调是什么意思?
    • 对不起,我不确定我明白你想说什么
    • @Steve 你试过我说你丢失的代码了吗?请试试看。
    猜你喜欢
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2022-08-05
    • 2017-10-05
    • 2015-09-23
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多