用 MongoDB 缩短用户密码哈希

User password hash cut short with MongoDB

我正在创建一个 MERN 应用程序,其路由基于角色身份验证受到限制。因此,当服务器启动时,它会在连接到 MongoDB 后寻找超级用户,如果找不到,则会提示创建超级用户:

(async () =>
{
    const MONGO_URI = process.env.MONGO_URI;
    await mongoose.connect(MONGO_URI, {
        useNewUrlParser: true,
    }).then(() => console.log("Mongo success")).catch(err => console.log(err));

    const User = require('./models/User');
    const Role = require('./_inc/role');
    const superUser = await User.findOne({ role: Role.Superuser });
    if (!superUser)
    {
        const readline = require('readline');
        const rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });
        rl._writeToOutput = function(str)
        {
            if (rl.stdoutMuted)
            {
                rl.output.write('*');
            }
            else
            {
                rl.output.write(str);
            }
        }
        const prom = (str, muted = false) => new Promise(resolve => {
            rl.question(str, resolve);
            rl.stdoutMuted = muted;
        });
        const username = await prom('Username: ');
        const email    = await prom('Email: ');
        const password = await prom('Password: ', true);
        rl.history = rl.history.slice(1);
        rl.close();
        const newUser = new User({
            name: username,
            email, password,
            role: Role.Diosito,
            picture: '',
            method: {
                local: true,
            },
        });
        bcrypt.genSalt(10, (err, hash) => {
            if (err) throw err;
            newUser.password = hash;
            newUser
              .save()
               .catch(err => console.log({
                    error: 'se ocurrió un error por intentar crear al usario'
                }));
        });
    }
})();

不幸的是,在某些时候密码哈希被缩短到前 29 个字符。 这是用户模式:

const userModel = {
    name: {
        type: String,
    },
    email: {
        type: String,
        unique: true,
    },
    picture: {
        type: String,
    },
    password: {
        type: String,
    },
    role: {
       type: String,
       required: true,
    },
    banned: {
        type: Boolean,
        default: false,
    },
    method: {
        google: Boolean,
        local:  Boolean,
    },
};
const UserSchema = new Schema(userModel);

感谢任何帮助,谢谢

您需要在 bcrypt.genSalt 回调中调用 bcrypt.hash 方法

bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash(password, salt, function(err, hash) {
        if (err) throw err;
            newUser.password = hash;
            newUser
              .save()
               .catch(err => console.log({
                    error: 'se ocurrió un error por intentar crear al usario'
                }));
    });
});

问题是 bcrypt.genSalt 只生成盐值,而不是散列密码,所以这就是密码被缩短的原因。您还需要致电 bcrypt.hash(password, salt)

bcrypt.genSalt(10, function(err, salt) {
  bcrypt.hash(password, salt, function(err, hash) {
    newUser.password = hash;
    newUser
      .save()
        .catch(err => console.log({
           error: 'se ocurrió un error por intentar crear al usario'
        }));
  });
});

您可以在此处阅读更多信息https://heynode.com/blog/2020-04/salt-and-hash-passwords-bcrypt/