为什么我的明文和盐不重合?

问题描述 投票:0回答:1

我正在开发一个api,我正在使用nodejs,express,sequelize,mysql。

我正在使用 bcrypt 和 jwt 实现我的身份验证路由和方法。我的用户注册工作正常,用户及其加密密码保存在我的数据库中。

我遇到的问题是,当我想对用户进行身份验证时,纯文本密码和哈希密码不匹配。

这是我在 users.js 中的路线

router.post('/', [
    
    check('email', 'Plese include a valid email').isEmail(),
    check('password', 'Password is required').exists()
], 
async (req, res)=> {
    const errors = validationResult(req);
    if(!errors.isEmpty()){
        return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
    }


    const { email, password } = req.body;

    try{

        // Validate emil & password
        if (!email || !password) {
            return next(new ErrorResponse('Please provide an email and password', 400));
        }

        //See if user exists
        let user = await User.findOne({ where: { email: email }, attributes: ['email', 'password'] });

        if(!user){
            return res.status(400).json({ errors: [{ msg:'Invalid credentials' }] });
        }

        //Compare the input password, plane text, to the encrypted password.
        const isMatch = await user.matchPassword(password);
        
        if(!isMatch){
            return res.status(400).json({ errors: [{ msg:'Invalid credentials' }] });
        }
    
        //Return jsonwebtoken -> this for users to be logged in right after registration
        sendTokenResponse(user, 200, res);

    }catch(err){
        console.error(err.message);
        res.status(500).send('Server Error');
    }
    

});

这是我在 user.model.js 中的用户模型

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../config/db');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

const User = sequelize.define('User', {
    id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    lastname: {
        type: DataTypes.STRING,
        allowNull: false
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
    },
    password: {
        type: DataTypes.STRING,
        allowNull: false
    }
});


User.addHook('beforeCreate', async (user, options) => {
    if (user.password) {
       const salt = await bcrypt.genSalt(10);
       user.password = await bcrypt.hash(user.password, salt);
    }
});
   
User.prototype.getSignedJwtToken = function() {
    return jwt.sign({ id: this.id }, process.env.JWT_SECRET, {
       expiresIn: process.env.JWT_EXPIRE
    });
};
   
User.prototype.matchPassword = async function(enteredPassword) {
    console.log(this);
    console.log(enteredPassword, this.password);
   console.log(await bcrypt.compare(enteredPassword, this.password));

   return await bcrypt.compare(enteredPassword, this.password);
};

module.exports = User;

如您所见,我的模型中有一些方法来加密我的密码,并将插入的纯文本密码与数据库中的哈希密码进行比较。

由于某种原因,当我正确输入凭据时,我的方法 matchPassword 始终返回 false。

我也会留下我的注册路线,以防万一我使用与

matchPassword

中使用的盐不同的盐对密码进行不同的加密
router.post('/register', [
    check('name', 'Name is required')
        .not()
        .isEmpty(),
    check('lastname', 'Lastname is required')
        .not()
        .isEmpty(),
    check('email', 'Plese include a valid email').isEmail(),
    check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
 ], 
 async (req, res) => {
    const errors = validationResult(req);
    if(!errors.isEmpty()){
        return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
    }
 
    const { name, lastname, email, password } = req.body;
 
    try {
        
        //Check if user exists
        let user = await User.findOne({ where: { email } });
 
        if(user){
            return res.status(400).json({ errors: [{ msg: 'User already exists'}]});
        }
 
        //Encrypt password
        const salt = await bcrypt.genSalt(10);
        hashedPassword = await bcrypt.hash(password, salt);


        //Create user
        user = await User.create({ name, lastname, email, password:hashedPassword });

        //Return jsonwebtoken -> this for users to be logged in right after registration

        sendTokenResponse(user, 200, res);
       
 
    } catch (error) {
        console.error('Error:', error);
        res.status(500).send('Server error');
    }
 
 });
node.js express jwt bcrypt
1个回答
0
投票

您使用了

hash
功能两次。

其中之一在您的模型定义中。

bcrypt.hash
位于
beforeCreate
挂钩中,另一个位于
register
控制器中。

如果您使用

bcrypt.hash
来加密密码,则无需在
register
控制器中使用它。您必须以纯文本形式传递密码。

如果我的回答能够解决您的问题,那将是我的荣幸。

谢谢你

© www.soinside.com 2019 - 2024. All rights reserved.