【问题标题】:User always getting failure redirected using passport?用户总是使用护照重定向失败?
【发布时间】:2021-04-16 00:26:09
【问题描述】:

无论我如何更改用户登录名,都会一直重定向到失败而不是成功。我不知道我是否遗漏了什么,或者我做错了什么。我试图阅读护照文件,但我发现它很混乱。如果您需要查看其余代码,这是我的 github 链接。节点文件位于 app.js 和 passport-config.js 中。网站的注册部分正在运行。 https://github.com/gego144/to-do-list-website/tree/main

const customFields = {
    usernameField: 'email',
    passwordField: 'password'
}

const verifyCallback = (username, password, done) => {
          user_exists = userName_Checker(username), function (err, user) {
            if (err) { return done(err); }
            if (userName_Checker(username) == false) {
                console.log('wrong user');
              return done(null, false, { message: 'Incorrect username.' });
            }
            if (password_finder(username, password)) {
                console.log('wrong pass');
              return done(null, false, { message: 'Incorrect password.' });
            }
            console.log('wtf');
            return done(null, user);
          };  
      ;

}

const strategy = new LocalStrategy(customFields, verifyCallback);

passport.use(strategy);

passport.serializeUser(function(user, done) {
    done(null, user);
});


passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
      done(err, user);
    });
});


// function that checks to see if the users email is in the database
function userName_Checker(email_name){
    
    var sql = "select * from info where email = ?";
    var user_email = [[email_name]];

    db.query(sql, [user_email],function (err,result){
        if (err) throw err;
        var not_unique = result.length;
        if(not_unique == 0){
            return false;
        }
        else{
            return true;
        }
    }
    )}


// function that checks to see if the password in the database matches with the email
function password_finder(email_name, pass){
    var sql = "SELECT password FROM info WHERE email = ?";
    var user_email = [[email_name]];
    db.query(sql, [user_email],function (err,result){
        if (err) throw err;
        
        bcrypt.compare(result, pass, function(err, res){
            if(err){ throw err};
            if(res){
                return true;
            }
            else{
                return false;
            }
        })
    }
)}

我在其他文件中的发布方法。

app.post('/login', passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect:'/index.html',
    failureFlash: true
}))

编辑 1。 我只想提一下,您在验证回调中看到的 console.logs 也出于某种原因也没有记录任何内容。

【问题讨论】:

  • 喜欢这个console.log('wtf');
  • 调试有时会令人沮丧,哈哈。

标签: mysql node.js express passport.js bcrypt


【解决方案1】:

问题可能出在序列化逻辑上。

passport.serializeUser 中,您传递的是整个user 对象,但在反序列化时,您传递的是id

虽然我没有使用SQL,但逻辑应该是类似的。

所以代码应该是这样的:

//  Session
// Pass in user id => keep the session data small
passport.serializeUser((id, done) => {
    done(null, id);
});

// Deserialize when needed by querying the DB for full user details
passport.deserializeUser(async (id, done) => {
    try {

        const user = await User_DB.findById(id);
        done(null, user);
    } catch (err) {

        console.error(`Error Deserializing User: ${id}: ${err}`);
    }

});
// Export the passport module
module.exports = (passport) => {

    passport.use(new LocalStrategy({ usernameField: 'email', }, async (email, password, done) => {

        try {

            // Lookup the user 
            const userData = await User_DB.findOne({ email: email, }, { 
            password: 1, }); // Return the password hash only instead of the whole user object

            // If the user does not exist
            if (!userData) {

                return done(null, false);
            }

            // Hash the password and compare it to the hash in the database
            const passMatch = await bcrypt.compare(password, userData.password);

            // If the password hash does not match
            if (!passMatch) {
                return done(null, false);
            }

            // Otherwise return the user id
            return done(null, userData.id);

        } catch (err) {
            passLog.error(`Login Error: ${err}`);
        }

    }));
};

这些护照选项似乎经常出现故障或表现出奇怪的行为,所以我建议你像在我的控制器中一样处理重定向逻辑。

{ successRedirect: '/good',
 failureRedirect: '/bad' }

登录控制器逻辑: (我在这里省略了用于会话存储的代码并进行了一些修改,但是这段代码应该可以满足您的需要)

const login = (req, res, next) => {

    //Using passport-local
    passport.authenticate('local', async (err, user) => {


        //If user object does not exist => login failed
        if (!user) { return res.redirect('/unauthorized'); }


        //If all good, log the dude in
        req.logIn(user, (err) => {

            if (err) { return res.status(401).json({ msg: 'Login Error', }); }

            // Send response to the frontend
            return res.redirect('/good');
        });

      
        });
    })(req, res, next);


};

实际路线:

//  Import the controller
const {login} = require('../controllers/auth');

// Use it in the route
router.post('/auth/login', login);

【讨论】:

  • 我尝试复制并粘贴您的代码来替换我的用户序列化,但它仍然重定向到失败。
  • 我收到错误“错误:找不到模块 '../controllers/auth”。 ''../controllers/auth" 是护照的一部分吗?
  • 没有。我的错。应该澄清../controllers/auth 是我存储控制器文件的地方。你知道控制器吗?而不是把所有东西都放在路线下。您可以将所有这些函数放在一个单独的文件中,并将它们作为中间件加载。它只是一种使代码更简单和模块化的方法。跟护照没有直接关系。
  • 我应该把module.export方法和log in方法都放在'controllers/auth'里面吗?我想知道,因为如果我这样做了,登录不是永远不会被调用吗?还是应该将登录方法放在我的 app.js 中并更改变量名?
  • 把护照本身(module.export)放到一个文件中。在文件中具有日志记录逻辑的控制器。和文件中的路线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 2017-09-27
  • 2019-03-08
  • 2013-05-27
  • 1970-01-01
  • 2016-05-06
相关资源
最近更新 更多