Ошибка Mongodb: невозможно установить заголовки после их отправки клиенту - PullRequest
0 голосов
/ 17 апреля 2020

Я в основном создаю форму регистрации пользователя, в которой я проверяю, совпадают ли представленные пароли, и затем проверяю, существует ли уже пользователь, запрашивая коллекцию, чтобы узнать, существует ли уже введенное имя пользователя или электронная почта. Если все данные прошли проверку, я создаю нового пользователя. Моя проблема в том, что если имя пользователя или адрес электронной почты уже существуют, то пользователь все еще создается. Не должен ли возврат статуса, если пользователь найден, остановить функцию?

Передача переднего плана:

submitNewUser() {
    axios.post('http://localhost:5000/api/settings/users', {
         name: this.newUser.name,
         username: this.newUser.username,
         email: this.newUser.email,
         password: this.newUser.password,
         confirm_password: this.newUser.confirm_password,
         role: this.newUser.role
    })
    .then(() => {
        this.getUsers();
    })
    .catch(error => {
        console.log(error);
    })
}

Пользователь должен войти в систему, чтобы создать нового пользователя, поэтому я проверяю паспорт пользователя, если токен содержит действительного пользователя

проверка подлинности паспорта check:

const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/User');
const key = require('./keys').secret;

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = key;

module.exports = passport => {
    passport.use(
        new JwtStrategy(opts, (jwt_payload, done) =>{
            User.findById(jwt_payload._id).then(user => {
                if (user) return done(null, user);
                return done(null, false);
            }).catch(err => {
                console.log(err);
            });
        })
    );
};

Конечный маршрут:

router.post('/users', passport.authenticate('jwt', {
    session: false
}), (req, res) => {
    let companyId = req.user.company_id;

    let {
        name,
        username,
        email,
        password,
        confirm_password,
        role,
    } = req.body;

    //Check that passwords match
    if( password !== confirm_password ) {
        return res.status(400).json({
            msg: "Passwords do not match"
        })
    }

    //Check for unique username 
    User.findOne({ username: username })
        .then(user => {
            console.log('username')
            if(user) {
                return res.status(400).json({
                    msg: "Username is already taken."
                });
            }
        })
        .catch(error => console.log(error));

    //check for unique email
    User.findOne({ email: email })
        .then(user => {
            console.log('email')
            if(user) {
                return res.status(400).json({
                    msg: "Email is already registered. Did you forget your password?"
                });
            }
        })
        .catch(error => console.log(error));

    let newUser = new User({
        name,
        username,
        password,
        email,
        user_role: role,
        company_id: companyId,
    });

    // Hash password
    bcrypt.genSalt(10, (err, salt) => {
        bcrypt.hash(newUser.password, salt, (err, hash) => {
            if(err) throw err;
            newUser.password = hash;
            newUser.save()
                .then(user => {
                    return res.status(201).json({
                        success: true,
                        msg: "User is now registered."
                    });
                })
                .catch(error => console.log(error));
        });
    });
});

Я получаю ошибку, если пользователь уже существует:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:482:11)
    at ServerResponse.header (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:267:15)
    at User.findOne.then.user (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\server\routes\api\settings.js:106:40)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)

1 Ответ

0 голосов
/ 17 апреля 2020

Из-за асинхронной природы c, (req, res) => { возвращается до того, как любой из ваших вызовов на mongodb будет либо успешным, либо неудачным, но вы все равно используете объект res для отправки ответа клиенту.

Я не знаю точно, как с этим справиться в используемой вами платформе, но, похоже, среда заполняет заголовок res данными и отправляет их обратно клиенту, прежде чем вы начнете изменять res объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...