Обновление хешированного пароля с mon goose express - PullRequest
0 голосов
/ 28 мая 2020

Я просмотрел много обсуждений по этому поводу, но ни одна из них не кажется мне полезной.

Я использую mon goose 5.5 для сохранения пользовательских данных, как показано ниже:

Моя схема выглядит так это:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const bcrypt = require("bcryptjs");

const userSchema = Schema({

  userName: {
    type: String
  },
  firstName: {
    type: String
  },
  surName: {
    type: String
  },
  password: {
    type: String,
    required: true
  }
});

userSchema.pre('save', async function(next){

try {
  if(!this.isModified('password')){
      return next();
  }
  const hashed = await bcrypt.hash(this.password, 10);
  this.password = hashed;

} catch (err) {
    return next(err);
  }
});

module.exports = user;

Мой регистрационный код выглядит так:

exports.register = async (req, res, next) => {

try {
    const user = await db.user.create(req.body);
    const {id, username} = user;
    res.status(201).json({user});

} catch (err) {
    if(err.code === 11000){
        err.message ='Sorry, details already taken';
    }
    next(err);
  }
};

Код входа выглядит так:

exports.login = async (req, res, next) => {

try {
    const user = await db.user.findOne({username: req.body.username});
    const valid = await user.comparePasswords(req.body.password);

    if(valid){

        const token = jwt.sign({id, username}, process.env.SECRET);
        res.json({id, username, token});
    }
    else{
        throw new Error();
    }        

} catch (err) {
    err.message = 'Invalid username/password';
    next(err);
  } 
};

Регистрация и вход в систему работают хорошо, моя задача обновляет пароль. Я хотел бы сравнить текущий пароль с тем, который предоставляет пользователь (например, при входе в систему), если он действителен, обновите новый пароль.

примерно так:

exports.changepass = async (req, res, next) => {
    const user = await db.user.findOne({username: req.body.username});
    const valid = await user.comparePasswords(req.body.password);

    if(valid){

           " ?? update password and hash ?? "
    }
    else{
        throw new Error();
    }       

}

Любезный совет

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Если вы используете findOneAndUpdate () для обновления, попробуйте использовать промежуточное ПО pre ("findOneAndUpdate") , чтобы изменить пароль, аналогичный вашему pre ("save ") . Промежуточное ПО pre ("findOneAndUpdate") будет вызываться каждый раз, когда вы используете Model.findOndAndUpate () для обновления ваших моделей.

Вы можете сделать то же самое с updateOne () с pre ("updateOne")

Пример:

// userSchema--------------------
...
userSchema.pre('save', async function (next) {
    try {
        if (!this.isModified('password')) {
            return next();
        }
        const hashed = await bcrypt.hash(this.password, 10);
        this.password = hashed;
    } catch (err) {
        return next(err);
    }
});

userSchema.pre('findOneAndUpdate', async function (next) {
    try {
        if (this._update.password) {
            const hashed = await bcrypt.hash(this._update.password, 10)
            this._update.password = hashed;
        }
        next();
    } catch (err) {
        return next(err);
    }
});

// changepass--------------------
...
if(valid){

    //" ?? update password and hash ?? "
    const result = await db.user.findOneAndUpdate(
        { username: req.body.username },
        { password: req.body.newPassword },
        { useFindAndModify: false }
    ); 
}
0 голосов
/ 08 июля 2020

Попробуйте этот метод. у меня работает нормально

userSchema.pre('findOneAndUpdate', async function (next) {
  const user = this;
  if (user._update.$set.password) {
    user._update.$set.password = await bcrypt.hash(user._update.$set.password, 8);
  }
  next();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...