Подтверждение пароля и внешняя проверка модели в Sails.js

Я играл с Sails, может быть, один день. Я пытаюсь понять, как лучше всего провести обширную проверку в Sails.js.

Вот сценарий:

Registration Form:

Username: _______________
E-Mail:   _______________
Password: _______________
Confirm:  _______________

Введенные пользователем данные:

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

Желаемый результат:

Username: _______________ x Already taken
E-Mail:   _______________ ✓
Password: _______________ ✓
Confirm:  _______________ x Does not match

Требования, несколько ключевых моментов:

  • Пользователь получает все сообщения об ошибках (а не только первое) для каждого аспекта своего ввода. Они не расплывчаты ("имя пользователя уже занято" или "имя пользователя должно состоять не менее чем из 4 букв" лучше, чем "недопустимое имя пользователя").
  • Встроенная проверка модели, очевидно, не может отвечать за проверку подтверждения совпадающего пароля (SRP).

Что, по моему мнению, мне нужно сделать:

Пользовательский контроллер:

create: function(req, res) {
    try {
        // use a UserManager-Service to keep the controller nice and thin
        UserManager.create(req.params.all(), function(user) {
            res.send(user.toJSON());
        });
    }
    catch (e) {
        res.send(e);
    }
}

Менеджер пользователей:

create: function(input, cb) {
    UserValidator.validate(input); // this can throw a ValidationException which will then be handled by the controller
    User.create(input, cb); // this line should only be reached if the UserValidator did not throw an exception
}

Пользователь: (модель)

attributes: {
    username: {
        type: 'string',
        required: true,
        minLength: 3,
        unique: true
    },

    email: {
        type: 'email',
        required: true,
        unique: true
    },

    password: {
        type: 'string',
        required: true
    }
}

Пользователь Валидатор:

Это сложная часть. Мне нужно объединить проверку ввода (соответствует ли подтверждение пароля?) с проверкой модели (занято ли имя пользователя и действителен ли адрес электронной почты?).

Если бы был способ создать экземпляр модели пользователя и выполнить проверку без сохранения в базе данных в Sails/Waterline, я думаю, это было бы довольно просто, но, похоже, такой возможности нет.

Как бы вы подошли к решению этой проблемы? Большое спасибо за Вашу помощь!


person Macks    schedule 21.02.2014    source источник


Ответы (2)


Будут некоторые проверки, которые вы можете выполнить немедленно на стороне клиента без необходимости обращения к серверу. Такие вещи, как сравнение пароля с паролем подтверждения, а также проверка совпадения строки с регулярным выражением электронной почты, можно выполнить с помощью javascript на стороне клиента.

Для других вещей, таких как проверка того, существует ли имя пользователя или нет, вы можете использовать вызов ajax для парусов, чтобы напрямую спросить его «существует ли это имя пользователя» и обеспечить проверку в реальном времени на стороне клиента на основе результата, или вы можете подождать пока пользователь не отправит форму и не проанализирует отправку формы, чтобы отобразить эти проверки. Поскольку предварительная проверка подобных вещей не надежна на 100% (т. е. кто-то может создать пользователя с таким именем после проверки, но до отправки формы), некоторые люди предпочитают отказаться от предварительной проверки и обрабатывать только ошибка после поста.

Waterline имеет собственный встроенный механизм проверки под названием Anchor, который основан на validator.js (ранее назывался node-validator). Полный список доступных проверок см. здесь . Я бы рекомендовал вместо определения отдельного уровня проверки определить метод, который анализирует сообщения проверки парусов и форматирует их таким образом, чтобы он был удобным для пользователя и согласованным.

Если вы хотите выполнить свои собственные проверки помимо того, что Waterline сделает за вас, вы можете сделать эти проверки внутри обратный вызов жизненного цикла, например, обратный вызов жизненного цикла beforeCreate(values, callback). Если вы обнаружите ошибки, вы можете передать их обратному вызову в качестве первого параметра, и они будут переданы обратно как ошибка вызывающей стороне метода создания коллекции.

Альтернативой использованию обратного вызова жизненного цикла может быть создание собственного метода коллекции, который обрабатывает создание. Что-то вроде этого:

Users.validateAndCreate(req.params.all(), function (err, user) {
    ...
});

Дополнительную информацию о том, как создать такой метод сбора, можно найти в моем ответе на этот вопрос: Как написать функцию паруса для использования в контроллере?

person Chad    schedule 24.02.2014
comment
Привет, Чад, спасибо, что помог мне! Я могу быть немного придирчивым к этому, но пользователю должно быть странно, что некоторые вещи проверяются на стороне клиента, а другие должны ждать ответа от сервера. С другой стороны, я думаю, вы могли бы возразить, что сервер не должен заботиться о сопоставлении паролей, потому что это в значительной степени просто пользовательский интерфейс. Но что происходит, когда мне нужно ввести проверку на стороне сервера, которая не может быть выполнена моделью? Как совместить это с проверкой модели в одном сообщении об ошибке? Это на самом деле суть моего вопроса. Спасибо еще раз! :) - person Macks; 25.02.2014
comment
Вам решать, насколько надежной должна быть проверка на стороне клиента. Вы можете быть настолько придирчивыми, насколько хотите, это ваше приложение :) Я добавил некоторые дополнительные детали в свой ответ, чтобы проверить адресную обработку за пределами того, что может предоставить модель. Вы можете выполнять кросс-модельные проверки, запросы API и т. д. внутри обратных вызовов жизненного цикла или пользовательских методов сбора. Одно из двух решений, скорее всего, будет соответствовать вашим потребностям. - person Chad; 25.02.2014
comment
Привет, Чад, спасибо за быстрый ответ! Эти обратные вызовы жизненного цикла могут мне помочь, мне нужно их проверить. Спасибо! - person Macks; 25.02.2014

Вы можете сделать это в своей модели:

module.exports = {
types: {
    mycustomtype: function (password) {
        return password === this.confirm;
    }
},
attributes: {,
    password:{
        type: 'STRING',
        required: true,
        mycustomtype: true
    }
}
}
person Raphael    schedule 05.03.2014