Я ошибаюсь? Меня смущают NodeJS, MongoDB, Joi, Bcrypt

У меня проблемы с NodeJS (ExpressJS), MongoDB, Joi Validation Module и Bcrypt.

У меня есть пользовательский API-маршрутизатор и пользовательская модель. Моя модель пользователя такова:

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        trim: true,
        minlength: [3, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                return /^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/.test(v);
            },
            message: 'Uygun Formatta İsim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)'
        },
        match: [/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/, 'Uygun Formatta İsim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)']
    },
    lastname: {
        type: String,
        trim: true,
        minlength: [3, 'Soyadınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                return /^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/.test(v);
            },
            message: 'Uygun Formatta Soyisim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)'
        },
        match: [/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/, 'Uygun Formatta Soyisim Giriniz. (Geçerli Karakterler: a-z, A-Z, boşluk karakteri.)']
    },
    username: {
        type: String,
        trim: true,
        index: true,
        unique: true,
        minlength: [3, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
        maxlength: [20, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
        validate: {
            validator: function(v) {
                let re = /^\w+$/;
                return re.test(v);
            },
            message: 'Uygun Formatta Kullanıcı Adı Giriniz. (Geçerli Karakterler: a-z, A-Z, _.)'
        },
        match: [/^\w+$/, 'Uygun Formatta Kullanıcı Adı Giriniz. (Geçerli Karakterler: a-z, A-Z, _.)']
    },
    email: {
        type: String,
        trim: true,
        index: true,
        unique: true,
        validate: {
            validator: function(v) {
                let re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
                return re.test(v);
            },
        message: 'Uygun Formatta E-Posta Adresi Giriniz.'
        },
        match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Uygun Formatta E-Posta Adresi Giriniz.']
    },
    password: {
        type: String,
        trim: true,
        required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
        minlength: 5,
        maxlength: 1024
    },
    elo: {
        type: Number,
        min: 0,
        required: false,
        default: 0
    },
    rank: {
        type: Number,
        min: -1,
        required: false,
        default: 0
    },
    registerDate: {
        type: Date,
        default: Date.now
    },
    isAdmin: {
        type: Boolean,
        required: true,
        default: false
    }
});

И это схема проверки Joi:

const Schema = {
    name: Joi.string().min(3).max(50).regex(/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/),
    lastname: Joi.string().min(3).max(50).regex(/^[A-Za-zıİüÜğĞşŞçÇöÖ ]+$/),
    username: Joi.string().required().min(3).max(25).regex(/^\w+$/),
    email: Joi.string().required().min(3).email(),
    password: Joi.string().required().min(5).max(255),
    elo: Joi.number().default(0).min(0),
    rank: Joi.number().default(0).min(-1),
    isAdmin: Joi.boolean().default(false)
};

Это образец пользователя:

_id:5b47aae43cf7710e7047c033
elo:0
rank:0
isAdmin:true
name:"Furkan"
lastname:"Taştan"
username:"praaven"
email:"[email protected]"
password:"$2b$10$4xKTxmQnV5mnGrCccpQsY.A8j5ACCdmCHIihDdW0NXmcOcRCcwwPq"
registerDate:2018-07-12 22:24:20.778
__v:0

Я не понимаю, как обновить маршрутизатор API.

router.put('/:id', auth, async (req, res) => {
    try {
        const errorId = validateUserId(req.params.id);
        if (errorId.error) return res.status(400).send({'Hata': errorId.error.details[0].message});
        const { error } = validateUser(req.body);
        if (error) return res.status(400).send({'Hata': error.details[0].message});
        const salt = await bcyript.genSalt(10);
        const user = await User.findByIdAndUpdate(req.params.id, {
            name: req.body.name,
            lastname: req.body.lastname,
            username: req.body.username,
            email: req.body.email,
            password: await bcyript.hash(req.body.password, salt),
            elo: req.body.elo,
            rank: req.body.rank,
            isAdmin: req.body.isAdmin
        }, { new: true, runValidators: true, context: 'query' });
        if (!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
        res.status(200).send(_.pick(user, ['_id', 'name', 'lastname', 'username', 'email', 'elo', 'rank', 'registerDate', 'isAdmin']));
    } catch(e) {
        res.status(400).send({ 'Hata': e.message.replace(/(Validation failed|email|username|phone|team)/gi, v => arrayMap[v]) });
    }
});

Проблема в том, зачем мне нужен пароль каждого пользователя обновления? Мне не нужен пароль пользователя, я хочу использовать его по желанию. Я думаю, мой Update Router ошибочен, я новичок в кодировании API RESTful на NodeJS, вы можете мне помочь с этим?

Спасибо, хорошего дня!

Ммм .. Значит, вы хотите обновить пароль, только если он был изменен?

B_CooperA 14.07.2018 15:55

@B_CooperA Да, то же самое. Я только что удалил .required() по паролю Joi Schema. После этого я сделал условие if для моего метода PUT, потому что if (пароль, определенный в полезной нагрузке) обновлял данные пользователя с паролем, иначе обновлял данные пользователя без пароля. И я решил эту проблему на данный момент. Это хорошо или есть подход лучше? Спасибо...

n3pixowe 14.07.2018 16:16

Я отправил ответ. Надеюсь, я правильно понял вашу проблему :)

B_CooperA 14.07.2018 16:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
450
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы уже проверяете поле пароля на уровне Schema здесь:

password: {
        type: String,
        trim: true,
        required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
        minlength: 5,
        maxlength: 1024
    },

поэтому нет необходимости повторно проверять его с помощью required() внутри схемы JOI.

Поскольку вы используете Mongoose, вы можете использовать функции pre внутри вашего userSchema. Как это:

/**
 * Hash password with blowfish algorithm (bcrypt) before saving it in to the database
 */
userSchema.pre('save', function(next) {
    var user = this;

    // only hash the password if it has been modified
    if (!user.isModified('password'))
        return next();

    // password will be hashed only if it has changed
    user.password = bcrypt.hash(user.password, bcrypt.genSalt(10));
    next();
});

Это действительно из-за required(), который вы добавили в свою схему JOI.

В качестве решения у вас есть несколько способов сделать это. Возможно, вы захотите предоставить другой API, чтобы специально разобраться с нюансами паролей и имени пользователя. Таким образом, вы в конечном итоге создаете две отдельные схемы JOI для работы с разными ситуациями - с изменением пароля, когда это действительно необходимо, и при обновлении деталей (я не уверен, что перемещение паролей вперед и назад при обновлении деталей - это приятное занятие. идея).

Дополнение: даже с учетом этого, я заметил, что вы на самом деле не выполняете здесь никаких преобразований (кроме пароля) над данными при передаче их из тела запроса в модель базы данных - и я не уверен, почему вы хотите проверить эти данные дважды для этого случая (помните, что вы также включили переключатель runValidators во время обновления).

Да, мне действительно не нужно использовать JOI, да?

n3pixowe 14.07.2018 17:03

@ n3pixowe Вы можете использовать либо проверку JOI, либо проверку схемы Mongoose во время обновления. Не нужно делать это дважды с одними и теми же данными в одно и то же мгновение, да.

nerdier.js 14.07.2018 22:20

Другие вопросы по теме