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

Модель пользователя

Класс модели пользователя User наследуется от areto/web/UserIdentity, который отвечает за интерфейс аутентификации пользователя. А также от класса areto/db/ActiveRecord, отвечающего за сохранение модели в базе данных.

models/User.js

'use strict';
const Base = require('areto/web/UserIdentity');
module.exports = class User extends Base {
  // place methods here
};
module.exports.init(module);
const security = require('areto/helpers/SecurityHelper');

В методе getConstants определяются статичные свойства класса.

  • TABLE - название таблицы, в которую сохраняется модель.
  • STORED_ATTRS - атрибуты модели, которые сохраняются в базу данных. В качестве идентификатора используется атрибут _id, который по умолчанию автоматически создается в MongoDB для каждой новой записи.

Статичные свойства доступны как через сам класса, так и его экземпляр: User.TABLE === (new User).TABLE === (new User).constructor.TABLE.

Для инициализации статичных свойств используется метод init, который вызывается сразу после определения класса. Аргументом ему передается значение текущего файла-модуля Node.js: module.exports.init(module).

models/User.js

...
static getConstants () {
  return {
    TABLE: 'user',
    STORED_ATTRS: ['name', 'email', 'role', 'status', 'passwordHash', 'authKey']
  };
}
...

Метод findIdentity находит в базе данных запись по указанному id и status === 'active'. Это необходимо при поиске идентифицированного пользователя по id, хранящемуся в сессии.

models/User.js

...
static findIdentity (id) {
 return this.findById(id).andWhere({status: 'active'});
}
...

Метод init вызывается сразу после создания модели. В нем проводится инициализация начальных значений атрибутов. При переопределении init для корректной работы класса необходимо вызывать родительский метод super.init.

models/User.js

...
init () {
  super.init();
  this.set('role', 'reader');
  this.set('status', 'active');
}
...

Метод getTitle отдает название модели для отображения в различных случаях. По умолчанию используется id.

models/User.js

...
getTitle () {
  return this.get('name');
}
...

Вспомогательные методы isActive, isBanned для проверки текущего статуса пользователя.

models/User.js

...
isActive () {
    return this.get('status') === 'active';
}

isBanned () {
    return this.get('status') === 'banned';
}
...

Метод getAssignments возвращает роль пользователя, хранящуюся в атрибуте role, что необходимо для авторизации доступа к ресурсам блога.

models/User.js

...
getAssignments (cb) {
  cb(null, [this.get('role')]);
}
...

Метод beforeSave вызывается перед сохранением модели. Метод асинхронный, поэтому по окончанию работы должен быть вызван callback cb. Также при переопределении необходимо вызывать родительский метод.

models/User.js

...
beforeSave (cb, insert) {
  super.beforeSave(err => {
    if (err) {
      return cb(err);
    }
    this.setPasswordHash();
    if (insert) {
      this.setAuthKey(cb)
    } else {
      cb();
    }
  }, insert);
}
...

Последняя пара методов отвечают за работу с паролем пользователя. Для этого используется вспомогательный класс areto/helpers/Security, который подключается после инициализации User. В базе данных сохраняется только хэш пароля, полученный алгоритмом sha1.

models/User.js

...
validatePassword (password) {
  return security.validatePassword(password, this.get('passwordHash'));
}

setPasswordHash () {
  if (this.get('password')) {
    this.set('passwordHash', security.encryptPassword(this.get('password')));
  }
}
...