PHP Framework for User Login & Registration – Software Recommendations Stack Exchange

Что делать дальше?

И вот мы подбираемся к самому интересному: а где хранить пароли и в каком виде? Давайте сначала подумаем, где их хранить.

Контроль доступа на основе ролей ¶

Контроль доступа на основе ролей (RBAC) — простой, но мощный способ централизованного
контроля доступа. Для сравнения данного метода с другими обратитесь к
статье в Википедии.

В Yii иерархический RBAC реализован через компонент authManager.
Ниже мы сначала опишем основы данной схемы, затем то, как описывать данные,
необходимые для авторизации. В завершение мы покажем, как использовать эти данные для
контроля доступа.

Что такое сессии?

Попробую рассказать в паре абзацев.

Сессии – это механизм, который позволяет однозначно идентифицировать пользователя.
По-человечески это значит, что для каждого посетителя сайта можно создать уникальное “хранилище”, к которому будет доступ только у этого самого посетителя.
Хранилище это хранится в файле на сервере.

На самом деле сессии хранятся не обязательно в файлах. Например, cms Modx хранит их базе данных.
Но сейчас нам это не важно, главное, что сессии предоставляют удобный способ работать с данными, уникальными для пользователя.
Для нас сессия выглядит как обычный ассоциативный массив под названием $_SESSION, в разные поля которого можно записать хоть число, хоть строку, хоть сериализованный объект.

Вход и выход ¶

Теперь, когда мы разобрали пример реализации класса identity, мы можем
использовать его для реализации входа и выхода:

Фильтр контроля доступа ¶

Фильтр контроля доступа — схема авторизации, подразумевающая предварительную проверку
прав текущего пользователя на вызываемое действие контроллера. Авторизация
производится по имени пользователя, IP-адресу и типу запроса. Данный фильтр называется
«accessControl».

Подсказка: Фильтр контроля доступа достаточен для реализации простых систем.
Для более сложных вы можете использовать доступ на основе ролей
(RBAC), который будет описан ниже.

Для управления доступом к действиям контроллера необходимо переопределить метод
CController::filters (более подробно описано в разделе
Фильтры).

Выше было описано, что фильтр access
control применяется ко всем действиям
контроллера PostController. Правила доступа, используемые фильтром, определяются
переопределением метода CController::accessRules контроллера.

class PostController extends CController
{
    …
    public function accessRules()
    {
        return array(
            array('deny',
                'actions'=>array('create', 'edit'),
                'users'=>array('?'),
            ),
            array('allow',
                'actions'=>array('delete'),
                'roles'=>array('admin'),
            ),
            array('deny',
                'actions'=>array('delete'),
                'users'=>array('*'),
            ),
        );
    }
}

Обработка запроса авторизации ¶

При неудачной авторизации, т.е. когда пользователю запрещено выполнять указанное
действие, происходит следующее:

При задании свойства loginUrl используется как относительный,
так и абсолютный URL. Также можно передать массив, который будет использоваться
CWebApplication::createUrl при формировании URL. Первый элемент массива
задаёт маршрут до действия login вашего
контроллера, а остальные пары имя-значение — GET-параметры. К примеру,

Настройка менеджера авторизации ¶

Перед тем, как мы перейдём к построению иерархии авторизации и непосредственно
проверке доступа, нам потребуется настроить компонент приложения
authManager. В Yii есть два типа менеджеров
авторизации: CPhpAuthManager и CDbAuthManager.

После этого мы можем обращаться к компоненту authManager
используя Yii::app()->authManager.

Построение иерархии авторизации ¶

Построение иерархии авторизации состоит из трёх этапов: задания элементов
авторизации, описания связей между ними и назначение ролей пользователям.
Компонент authManager предоставляет полный набор
API для выполнения поставленных задач.

Для определения элемента авторизации следует воспользоваться одним из приведённых
ниже методов:

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

После этого мы назначаем роли пользователям:

Приведём пример построения иерархии авторизации с использованием данного API:

$auth=Yii::app()->authManager;
 
$auth->createOperation('createPost','создание записи');
$auth->createOperation('readPost','просмотр записи');
$auth->createOperation('updatePost','редактирование записи');
$auth->createOperation('deletePost','удаление записи');
 
$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','редактирование своей записи',$bizRule);
$task->addChild('updatePost');
 
$role=$auth->createRole('reader');
$role->addChild('readPost');
 
$role=$auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
 
$role=$auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
 
$role=$auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');
 
$auth->assign('reader','readerA');
$auth->assign('author','authorB');
$auth->assign('editor','editorC');
$auth->assign('admin','adminD');

После создания элементов авторизации, компонент authManager
(или его наследники, например, CPhpAuthManager, CDbAuthManager) загружает их автоматически.
То есть, приведённый код запускается один раз, а НЕ для каждого запроса.

Инфо: Довольно громоздкий пример выше предназначен скорее для демонстрации.
Разработчикам обычно требуется создать интерфейс администратора и дать возможность
пользователям самим построить иерархию авторизации.

Использование бизнес-правил ¶

При построении иерархии авторизации мы можем назначить роль, задачу или операцию
бизнес-правилу. Также мы можем указать его при назначении роли пользователю.
Бизнес-правило — PHP-код, использующийся при проверке доступа. Возвращаемое данным кодом
значение определяет, применять ли данную роль к текущему пользователю.

В примере выше мы применили бизнес-правило для описания задачи updateOwnPost.
В нём мы проверяем, совпадает ли ID текущего пользователя с ID автора записи.
Информация о записи в массиве $params передаётся разработчиком при проверке
доступа.

Composer support

PHPAuth can now be installed with the following command:

composer require phpauth/phpauth:dev-master

Then: require ‘vendor/autoload.php’;

Configuration

The database table config contains multiple parameters allowing you to configure certain functions of the class.

Contributing

Anyone can contribute to improve or fix PHPAuth, to do so you can either report an issue (a bug, an idea…) or fork the repository, perform modifications to your fork then request a merge.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!

Custom config sources

By default, config defined at phpauth_config data table.

It is possible to define custom config from other sources: ini-file, other SQL-table or php-array:

  • config_source
    • for ‘sql’: name of custom table with configuration
    • for ‘ini’: path and name of INI file (for example: ‘$/config/config.ini’, ‘$’ means application root)
    • for ‘array’: it is a array with configuration
  • config_type:
    • ‘sql’ (or empty value) – load config from database,
    • ‘ini’ – config must be declared in INI file (sections can be used for better readability, but will not be parsed)
    • ‘array’ – config will be loaded from $config_source (type of array)
  • config_language – custom language for site as locale value (default is ‘en_GB’)

Examples:

new Config($dbh); // load config from SQL table 'phpauth_config', language is 'en_GB'

new Config($dbh, 'my_config', ''); // load config from SQL table 'my_config', language is 'en_GB'

new Config($dbh, '$/config/phpauth.ini', 'ini'); // configuration will be loaded from INI file, '$' means Application basedir

new Config($dbh, $CONFIG_ARRAY, 'array'); // configuration must be defined in $CONFIG_ARRAY value

new Config($dbh, '', '', 'ru_RU'); // load configuration from default SQL table and use ru_RU locale

Documentation

All class methods are documented in the Wiki
System error codes are listed and explained here

Donation

You can help with a donation, so we can rent servers to test on, we can tip our contributors as thank for their help.

Bitcoin: 1PrXRMb9R8GkSRB8wSJ2MWhF9cc6YXCS8w

Message languages

The language for error and success messages returned by PHPAuth can be configured by passing in one of
the available languages as the third parameter to the Auth constructor. If no language parameter is provided
then the default en_GBlanguage is used.

Example: $auth = new PHPAuthAuth($dbh, $config, “fr_FR”);

Available languages:

  • ar-TN
  • bs-BA
  • cs_CZ
  • da_DK
  • de_DE
  • en_GB (Default)
  • es_MX
  • fa_IR
  • fr_FR
  • gr_GR
  • hu_HU
  • id_ID
  • it_IT
  • nl_BE
  • nl_NL
  • no_NB
  • pl_PL
  • ps_AF
  • pt_BR
  • ro_RO
  • ru_RU
  • se_SE
  • sk_SK
  • sl_SI
  • sr_RS
  • th_TH
  • tr_TR
  • uk_UA
  • vi_VN
  • zh_CN
  • zh_TW

Requirements

  • PHP 7.1
  • MySQL / MariaDB database or PostGreSQL database

Выбираем правильное хэширование


Идею хранения паролей нашли, то есть хранения не паролей, а их хэшей. А вот какой алгоритм хэширования выбрать?

Давайте посмотрим на то, что пробовали выше – простая функция md5. Алгоритма его расшифровки нет, но тем не менее md5 не рекомендуется для использования. Почему?

Помимо сложности самого алгоритма, есть и другой момент. Да, расшифровать пароль по хэшу нельзя, но его можно подобрать. Простым брутфорсом.
К тому же существуют многочисленные базы паролей md5, где всевозможные варианты хранятся тупо списком.
И подбор вашего пароля по известному хэшу займет столько времени, сколько понадобится для выполнения sql-запроса

    select password from passwords where hash='e10adc3949ba59abbe56e057f20f883e';

Конечно, вы сами не будете использовать пароль 123456, но как насчет ваших пользователей? Да, 123456 можно подобрать и руками, но в таком случае никакие алгоритмы не помогут.
Наша же задача максимально позаботиться о юзерах, которые выбирают пароли сложнее qwerty. Думаем дальше, гуглим.

Помимо md5 есть множество алгоритмов хэширования, sha256, sha512 и еще целая толпа. Их сложность выше, но это не отменяет опять-таки существования таблиц с готовыми паролями.
Нужно что-то хитрее.

Заглушка для авторизации

Функции, связанные с авторизацией, будут лежать в отдельном файле и своем пространстве имен. Создадим файл auth.php в api/v1/common – там, где уже лежит helpers.php.
Если вы разбирали уроки админки, особенно третий, про серверную часть, то эти пути вам будут знакомы. Если у вас свой проект, то кладите auth.php куда удобно.
Главное, потом правильно указать пути.


Содержимое auth.php

Использование ролей по умолчанию

Некоторым веб-приложениям требуются очень специфичные роли, которые назначаются
каждому или почти каждому пользователю. К примеру, нам необходимо наделить некоторыми
правами всех аутентифицированных пользователей. Определять явно и хранить роли для
каждого пользователя в этом случае явно неудобно. Для решения этой проблемы можно
использовать роли по умолчанию.

Как обойтись без шифрования. хэширование

Фокус в том, что не нужно хранить пароли в открытом виде, но и не нужно шифровать их с возможностью расшифровки. Пароли нужно хэшировать и в базе хранить не пароль, а его хэш.
Хитрым образом закодированную строку, которую нельзя расшифровать. Например, не password, а 5f4dcc3b5aa765d61d8327deb882cf99

Вы можете спросить, что это за хрень и как же сравнить пароль, введенный пользователем, с паролем, лежащим в базе. А нам и не нужно сравнивать пароли – достаточно сравнить их хэши.


Например, есть простая функция хэширования md5. Вот так она работает

Общие принципы

Основным понятием в RBAC Yii является элемент авторизации. Элемент авторизации —
это права на выполнение какого-либо действия (создать новую запись в
блоге, управление пользователями). В зависимости от структуры и цели,
элементы авторизации могут быть разделены на операции,
задачи и роли.

Роль состоит из задач. Задача состоит из операций.
Операция — разрешение на какое-либо действие (дальше не делится).
К примеру, в системе может быть роль администратор, состоящая из задач
управление записями и управление пользователями.

Задача управление пользователями
может состоять из операций создать пользователя, редактировать пользователя и
удалить пользователя. Для достижения большей гибкости, роль в Yii может состоять
из других ролей и операций. Задача может состоять из других задач. Операция — из
других операций.

Элемент авторизации однозначно идентифицируется его уникальным именем.

Элемент авторизации может быть ассоциирован с бизнес-правилом — PHP-кодом,
который будет использоваться при проверке доступа. Пользователь получит доступ
к элементу только если код вернёт true. К примеру, при определении операции updatePost,
будет не лишним добавить бизнес-правило, проверяющее соответствие ID пользователя
ID автора записи. То есть, доступ к редактированию записи имеет только её автор.

Используя элементы авторизации мы можем построить иерархию авторизации.
Элемент A является родителем элемента B в иерархии, если
A состоит из B (или A наследует права, представленные в B).

После построения иерархии авторизации мы можем назначать роли из неё пользователям
нашего приложения. Пользователь получает все права роли, которая ему назначена.
К примеру, если назначить пользователю роль администратор, он получит административные
полномочия, такие как управление записями или управление пользователями
(и соответствующие им операции, такие как создать пользователя).

А теперь самое приятное. В действии контроллера мы хотим проверить, может
ли текущий пользователь удалить определённую запись. При использовании иерархии RBAC и
назначенной пользователю роли, это делается очень просто:

Проверяем работоспособность vue

Вроде бы, чего там может сломаться? Нам же практически не пришлось лезть в код vue, за исключением добавления кнопки Выйти в шапке админки.


Но попробуем пересобрать админку, чтобы убедиться, что все хорошо. Сначала в production режиме

    npm run build

Хранение паролей в базе данных

Безопасное хранение паролей в базе данных требует определённой аккуратности. Атакующий, получивший доступ к базе или
резервным копиям, может восстановить пароли, используя достаточно распространённые приёмы, если от них не защититься.
Пример кода выше использует встроенный класс CPasswordHelper, доступный с версии 1.1.14, для хеширования и проверки
пароля. CPasswordHelper::hashPassword возвращает стойкий ко взлому хеш.

Вместо заключения

Проблемы с dev режимом во vue – это неприятный момент. Мы хотим и апишечку подергать, и все удобства vue-cli использовать. И на елку влезть, и ничего не ободрать.
Возможно, есть более изящный способ обойти эти проблемы в dev режиме, но я их пока не нашел. Поэтому приходится подпирать код лишними условиями.

Похожее:  Веб-интерфейс роутера. Что это? Как войти?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *