Node.JS / Passport / Sequelize - 使用错误密码登录

Node.JS / Passport / Sequelize - Login with wrong password

我正在学习本教程 https://shorturl.at/ghnO9 使用 NodeJS、Passport 和 Sequelize

结构几乎相同(至少我认为是),因为 Sing Up 部分工作正常。

但是,当我使用错误的密码登录时,我登录成功了。

我的 passport.js 是这样写的:

var bCrypt = require('bcrypt');
const { reject } = require('bcrypt/promises');
const { resolveInclude } = require('ejs');
const passport = require('passport');

module.exports = function(passport,user){
var User = user;
var LocalStrategy = require('passport-local').Strategy;


//Login session
passport.use('local-signin', new LocalStrategy( 
{
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
 }, 
function(req, email, password, done) {
    var User = user;
    var isValidPassword = async function(userpass, password) {
        return bCrypt.compareSync(password, userpass);
    }
    User.findOne({
        where: {
            email: email
        }
    }).then(function(user) {
        if (!user) {
            return done(null, false, {
                message: 'Email does not exist'
            });
        }
        if (!isValidPassword(user.password, password)) {
            return done(null, false, {
                message: 'Incorrect password.'
            });
        }
        var userinfo = user.get();
        return done(null, userinfo);
    }).catch(function(err) {
        console.log("Error:", err);
        return done(null, false, {
            message: 'Something went wrong with your Signin'
        });
    });
}
));

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

//deserialize
passport.deserializeUser(function(id,done){
User.findByPk(id).then(function(user){
    if(user){
        done(null, user.get());
    } else {
        done(user.errors, null);
    }
});

我不知道这是否是旧的和过时的教程,我应该更改一些参数。我正在努力寻找有关 Passport 和 Sequelize 的任何其他教程,因此非常感谢您的帮助。谢谢!

您的 link 已损坏(最好 - 不要使用 link 缩短器并将整个 link 粘贴到其中,或者更好 - 在问题中内联相关信息)。

但我还是看到了你的问题:

  1. 不是原因,但仍然相关 - 您正在创建 User 变量两次(不知道为什么您仍然需要它,因为 user 已经可用- 你是想别名还是什么?)

  2. 实际问题 - 你的 isPasswordValid 函数是 async,但你没有用 await 调用它 - 这导致 Promise<boolean> 得到返回而不仅仅是一个 boolean,并且 Promise 总是真实的,因此这个

if (!isValidPassword(user.password, password)) {

将始终评估为 false,表示用户通过了登录。


建议:如果您使用 bCrypt.compareSync,名称本身就表明它 是同步的 ,这意味着您不需要函数是 async .这是您需要的:

-var isValidPassword = async function(userpass, password) {
+var isValidPassword = function(userpass, password) {
    return bCrypt.compareSync(password, userpass);
}

这会解决问题。但我们还没有完成。

我自己使用过 bcrypt,我应该警告同步比较(和散列)应该 在 nodejs 服务器的上下文中使用,因为它们可以减慢你的服务器速度 and/or 当一些用户尝试注册/登录等时阻止其他用户使用它,因为同步方法占用主线程并且在该任务完成之前,你的服务器不能做任何其他事情。出于这个原因,应该使用异步方法(并且不仅与 bcrypt 一起使用,而且当我们处于 nodejs 服务器环境中时,与大多数实用程序等一起使用)。


一般来说,authentication/authorization 真的很容易出错(就像你的情况一样),而且在你更熟悉你正在使用的编程语言的一般概念之前,除了其他因素以及 - 我建议避免尝试自己实现这个关键层(假设你正在将你的应用程序运送到生产环境!出于学习目的,这很好:))。

我还建议您找到更多 up-to-date 教程。

祝你好运!