Почему я получаю ошибку 400 при входе пользователя в систему с помощью bcrypt? - PullRequest
1 голос
/ 08 июля 2019

Я пытаюсь создать аутентификацию при входе в систему, но в Postman я получаю ошибку 400, в которой говорится, что мой синтаксис неверен при тестировании.Я почти уверен, что вся моя модель User является надежной, но для хорошей меры я приложил все это на случай, если что-то не так.В противном случае, я действительно не уверен, в чем проблема или куда идти дальше.

Данные, которые я отправляю, вызывают 400 неверный запрос (запрос не может быть выполнен из-за неправильного синтаксиса) и записывают неверный пароль на консоль:

{
    "email": "andrew@example.com",
    "password": "Red12345!"
}

Вот весь мой код модели пользователя:

const mongoose = require('mongoose')
const validator = require('validator')
const bcrypt = require('bcryptjs')

const userSchema = new mongoose.Schema({ 
    name: {
        type: String,
        required: true, 
        trim: true
    }, 
    email: {
        type: String,
        unique: true,
        require: true,
        trim: true, 
        lowercase: true,
        validate(value) {
            if(!validator.isEmail(value)) {
                throw new Error('Email is invalid')
            }
        }
    },
    age: {
        type: Number,
        default: 0,
        validate(value) {
            if(value < 0) {
                throw new Error('Age must be a positive number.')
            }
        }
    },
    password: {
        type: String,
        trim: true,
        lowercase: true,
        required: true,
        minlength: 7,
        validate(value) {
            if(value.toLowerCase().includes("password")) {
                throw new Error("Password can't be 'password'.")
            }
        }
    }
})

userSchema.statics.findByCredentials = async (email, password) => {
    const user = await User.findOne({ email })

    if (!user) {
        throw new Error('User not found')
    }

    const isMatch = await bcrypt.compare(password, user.password)

    if (!isMatch) {
        throw new Error('Invalid password')
    }

    return user
}

//Hash the plain text password before saving
userSchema.pre('save', async function (next) {
    const user = this

    if(user.isModified('password')) {
        user.password = await bcrypt.hash(user.password, 8)
    }

    next() 
})

const User = mongoose.model('User', userSchema)

module.exports = User

А вот маршрутизатор входа пользователя:

router.post('/users/login', async (req, res) => {
    try {
        const user = await User.findByCredentials(req.body.email, req.body.password)
        res.send(user)
    } catch (e) {
        console.log(e.message)
        res.status(400).send()
    }
})

1 Ответ

0 голосов
/ 08 июля 2019

трудно отследить ваш код. также вы продолжаете отправлять res.send(user). это также вернет пароль. Это не имеет смысла. вы должны опустить свойство пароля при его отправке.

пароль хеширования или пароль для сравнения должны быть внутри маршрутизаторов, чтобы у вас был один источник правды. Похоже, вы пишете API-интерфейс restful, поэтому у вас должен быть маршрутизатор / users, где вы хэшируете пароль.

/ пользователей

router.post("/users", async (req, res) => {
  const user = new User(_.pick(req.body, ["name", "email", "password", "age"]));

  try {
    const salt = await bcrypt.genSalt(10);
    user.password = await bcrypt.hash(user.password, salt);
    await user.save();
    res.status(201).send(_.pick(user, ["name", "email", "age"]));
  } catch (e) {
    res.status(500).send(e.message);
  }
});

/ пользователи / Логин

router.post("/users/login", async (req, res) => {
  const user = await User.findOne({ email: req.body.email });
  if (!user) {
    return res.status(400).send("invalid email or password");
  }
  const validPassword = await bcrypt.compare(req.body.password, user.password);
  if (!validPassword) {
    res.status(401).send("error");
  }
  //implementation of web token here and send the token
  //res.send(token)
  res.send("test")//for now test the route
});

_. * Выбрать 1013 * (Objectname, arrayOfProperties). это равно этому:

const user = new User(_.pick(req.body, ["name", "email", "password", "age"]));
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
age: req.body.age})

вот ссылка: https://lodash.com/docs/4.17.11#pick

...