Строим блог на Areto фреймворк

Форма входа

Форма входа принимает логин/пароль и ищет в базе соответствующую запись пользователя.

Форма входа пользователя

model/SignInForm.js

const CAPTCHA_SCENARIO = 'captcha';
const Base = require('areto/base/Model');

module.exports = class SignInForm extends Base {
};
module.exports.init(module);

const RateLimit = require('areto/security/rate-limit/RateLimit');
const PasswordAuth = require('../component/auth/PasswordAuth');

Валидация формы необходима, чтобы фильтровать некорректные значения ввода.

model/SignInForm.js

static getConstants () {
  return {
    RULES: [
      [['email', 'password'], 'required'],
      ['email', 'email'],
      ['password', 'string', {min: 6, max:24}],
      ['rememberMe', 'boolean'],
      ['captchaCode', 'required', {on: [CAPTCHA_SCENARIO]}],
      ['captchaCode', {
        Class: require('areto/security/captcha/CaptchaValidator'),
        on: [CAPTCHA_SCENARIO]
      }]
    ],
    ATTR_LABELS: {
      rememberMe: 'Remember me',
      captchaCode: 'Verification code'
    },
    CAPTCHA_SCENARIO
  };
}

Метод login проверяет данные формы. Если ошибок нет, то передает управление checkUser для поиска пользователя в базе.

model/SignInForm.js

async login () {
  await this.validate();
  if (!this.hasError()) {
    let result = await this.createPasswordAuth().login();
    if (result.error) {
        this.addError('email', result.error);
    }
    await this.updateRateLimit();
    this.toggleCaptchaScenario();
  }
}

В методе checkUser пользователь ищется по уникальному логину, в роли которого выступает email. Если пользователь с данным email существует, то будет создан экземпляр класса User. Дальнейшие проверки пользователя осуществляют методы этого класса.

Обратите внимание на одинаковый ответ сервера в случае не найденного логина и неправильного пароля. Этим закрывается возможность для посторонних узнать существует ли данный логин в базе.

Помимо пароля проверяется статус учетной записи. Если пользователь заблокирован, то сервер вернет соответствующее сообщение об ошибке входа.

После успешных проверок в методе webuser.login осуществляется привязка текущей пользовательской сессии к найденному пользователю. Если на форме был отмечен чекбокс rememberMe, то в куки броузера будет добавлена информация для автоматического входа пользователя на указанный период.

model/SignInForm.js

constructor (config) {
  super({
    // user: [new WebUser]
    rateLimit: config.module.get('rateLimit'),
    rateLimitType: 'signIn',
    rememberPeriod: 7 * 24 * 3600,
    ...config
  });
}

createPasswordAuth () {
  return this.spawn(PasswordAuth, {
    email: this.get('email'),
    password: this.get('password'),
    rememberMe: this.get('rememberMe'),
    user: this.user
  });
}

updateRateLimit () {
  if (this._rateLimitModel) {
    if (this.hasError()) {
      await this._rateLimitModel.increment();
    }
    if (this.isCaptchaRequired()) { // captcha has been validated
      await this._rateLimitModel.reset();
    }
  }
}