Автор оригинала: David Wong.
Набросок
В процессе разработки программы нельзя игнорировать вопросы безопасности. Независимо от того, насколько совершенна ваша структура, в ней будут недостатки. Поэтому совершенствуйте свою собственную систему, думайте с точки зрения безопасности разработки программ и подавляйте все потенциальные кризисы в колыбели.
Идентификация
Аутентификация-это процесс идентификации пользователей.
Обычно он использует идентификатор (например, имя пользователя или адрес электронной почты) и зашифрованный маркер (например, пароль или маркер доступа) для идентификации пользователя.
Аутентификация является основой логической функции. Yii предоставляет платформу аутентификации, которая соединяет различные компоненты для поддержки входа в систему. Чтобы использовать этот фреймворк, вам необходимо выполнить следующую работу:
Настройка пользовательского компонента yii веб-пользователь;
Создайте класс для реализации интерфейса yii web Identity Interface.
Настройка веб-пользователя yii
Пользовательский компонент yii web User используется для управления статусом аутентификации пользователя.
Для этого необходимо указать класс аутентификации yii web User:: класс идентификации, который содержит фактическую логику аутентификации.
В элементах конфигурации следующих веб-приложений класс аутентификации yii web User:: Класс идентификации пользовательского компонента yiiwebUser настроен как класс модели appmodelsUser.
return [
'components' => [
'user' => [
'identityClass' => 'app\models\User',
],
],
];Реализация интерфейса аутентификации yii интерфейс веб-идентификации
Класс аутентификации yii web User:: класс идентификации должен реализовывать интерфейс аутентификации yiiwebIdentityИнтерфейс, содержащий следующие методы:
Интерфейс веб-идентификации Yii:: Найти идентификатор (): Найдите экземпляр класса модели аутентификации на основе указанного идентификатора пользователя, который используется, когда вам нужно использовать сеанс для поддержания статуса входа.
Интерфейс веб-идентификации Yii:: findIdentityByAccessToken (): Найдите экземпляр класса модели аутентификации на основе указанного маркера доступа, который используется для аутентификации пользователей с помощью одного маркера шифрования (например, приложения RESTful без сохранения состояния).
Интерфейс веб-идентификации Yii:: getId (): Возвращает идентификатор пользователя, представленного экземпляром аутентификации.
Интерфейс веб-идентификации Yii:: getAuthKey (): Возвращает ключ аутентификации, используемый для входа в систему на основе файлов cookie. Ключи аутентификации хранятся в файлах cookie и в будущем будут сравниваться с версиями на стороне сервиса для обеспечения эффективности файлов cookie.
Интерфейс веб-идентификации Yii:: validateAuthKey (): Логическая реализация аутентификации на основе ключа входа в файл cookie.
Например, ваш проект-это просто приложение для отдыха без сохранения состояния. Вам просто нужно реализовать интерфейс веб-идентификации yii:: findIdentityByAccessToken () и интерфейс веб-идентификации yii:: getId () и оставить тело других методов пустым.
Следующий пример представляет собой класс аутентификации yii web User:: класс идентификации, реализованный путем объединения активной записи модели AR с таблицей пользовательских данных.
Как упоминалось выше, если ваше приложение входит в систему с использованием файлов cookie, вам нужно только реализовать методы getAuthKey () и validateAuthKey (). Таким образом, вы можете использовать следующий код для создания и хранения ключа аутентификации каждого пользователя в таблице пользователей.
class User extends ActiveRecord implements IdentityInterface{
......
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = \Yii::$app->security->generateRandomString();
}
return true;
}
return false;
}
}Примечание: Не путайте классы аутентификации пользователей с пользовательским компонентом yii web User. Первый – это класс, реализующий логику аутентификации. Обычно это реализуется с помощью активной записи модели AR, которая связывает информацию о пользователе, хранящуюся постоянно. Последний является компонентом приложения, отвечающим за управление статусом аутентификации пользователя.
Использование пользовательского компонента yii веб-пользователь
Что касается компонентов пользовательского приложения, вы в основном используете веб-пользователя yii.
Вы можете использовать выражение Yii:: $приложение – > Пользователь – > удостоверение, чтобы определить текущее удостоверение пользователя. Он возвращает экземпляр класса аутентификации yii web User:: класс идентификации, представляющий текущего вошедшего в систему пользователя, а неавторизованный пользователь (посетитель) возвращает значение null.
Следующий код показывает, как получить другую информацию, связанную с аутентификацией, от веб-пользователя yii:
// The current user's identity instance. Null is the unauthenticated user. $identity = Yii::$app->user->identity; // ID of the current user. Null is the unauthenticated user. $id = Yii::$app->user->id; // Determine whether the current user is a tourist (unauthenticated) $isGuest = Yii::$app->user->isGuest;
Вы можете войти в систему пользователя, используя следующий код:
// Gets the user identity instance using the specified user name. // Please note that you may need to verify your password if necessary. $identity = User::findOne(['username' => $username]); // Login user Yii::$app->user->login($identity); The yii web User:: login () method registers the identity of the current user to yii web User.
Если для сеанса установлено значение yii web User:: enableSession, сеанс используется для записи личности пользователя, и статус аутентификации пользователя будет сохраняться в течение всего сеанса.
Если включен автоматический вход в систему yii web User:: enableAutoLogin, для сохранения личности пользователя будет использоваться логин на основе файлов cookie (например, запоминание статуса входа), чтобы статус входа можно было восстановить, пока файл cookie действителен.
To log in using cookies, you need to set yii web User:: enableAutoLogin to true in the application configuration file. You also need to pass in the yii web User:: login () method the validity parameter (remember the length of login status).
Пользователь для выхода из системы:
Yii::$app->user->logout();
Обратите внимание, что имеет смысл выходить из системы пользователей, когда сеанс включен. Этот метод очистит статус аутентификации пользователя из памяти и сеанса одновременно.
По умолчанию он также выводит из системы все данные сеанса пользователя.
If you want to keep the session data, you can replace it with Yii:: $app - > User - > logout (false).
События аутентификации
Класс веб-пользователя yii вызывает некоторые события в процессе входа и выхода из системы.
1. yii web User:: EVENT_BEFORE_LOGIN: triggered when login yii web User:: login ().
If the event handle sets the yii web UserEvent:: isValid attribute of the event object to false, the login process will be cancelled.
2. yii web User:: EVENT_AFTER_LOGIN: Raised after successful login.
3. Yii web User:: EVENT_BEFORE_LOGOUT: triggered before the cancellation of yii web User:: logout ().
If the event handle sets the yii web UserEvent:: isValid attribute of the event object to false, the logout process will be cancelled.
4. yii web User:: EVENT_AFTER_LOGOUT: triggered after successful logout.Реагируя на эти события, вы можете выполнять некоторые функции, такие как статистика входа в систему и статистика онлайн-номеров. Например, в обработчике yii web User:: EVENT_AFTER_LOGIN после входа в систему вы можете записать время входа пользователя и IP-адрес в таблицу пользователей.
Авторизация
Авторизация относится к процессу проверки того, разрешено ли пользователю что-либо делать.
Yii предоставляет два метода авторизации: фильтр управления доступом (ACF) и управление доступом на основе ролей (RBAC).
Фильтр Контроля Доступа
Фильтр контроля доступа (ACF) – это простой метод авторизации, реализованный с помощью класса контроля доступа yii filters, который очень подходит для приложений, требующих только простого контроля доступа.
Как следует из названия, ACF-это фильтр действий, который может использоваться в контроллере или модуле. Когда пользователь запрашивает действие, RACF проверяет список yii фильтры управления доступом:: правила, чтобы определить, разрешено ли пользователю выполнять запрошенное действие. (Примечание переводчика: Действие переводится в действие, операцию, метод и т.д. как это уместно в этой статье)
Следующий код показывает, как использовать ACF в контроллере сайта:
use yii\web\Controller;
use yii\filters\AccessControl;
class SiteController extends Controller{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['login', 'logout', 'signup'],
'rules' => [
[
'allow' => true,
'actions' => ['login', 'signup'],
'roles' => ['?'],
],
[
'allow' => true,
'actions' => ['logout'],
'roles' => ['@'],
],
],
],
];
}
// ...
}В приведенном выше коде ACF прикрепляется к контроллеру сайта в форме поведения. Это типичный способ использования фильтров действий.
Единственный параметр указывает, что RACF должен работать только с методами входа, выхода и регистрации. Методы во всех других контроллерах сайта не ограничены контролем доступа.
В опции правила перечислены правила доступа к фильтрам yii, которые интерпретируются следующим образом:
Всем посетителям (неавторизованным пользователям) разрешается выполнять операции входа и регистрации. Опция роли содержит знак вопроса? Это специальный логотип, который представляет “посетителя-пользователя”.
Разрешить пользователям, прошедшим проверку подлинности, выполнять операции выхода из системы. @ Это еще один специальный идентификатор, который представляет “аутентифицированных пользователей”.
ACF проверяет правила доступа сверху вниз, пока не найдет правило, соответствующее текущей операции. Значение параметра разрешить в правиле сопоставления затем используется для определения того, авторизован ли пользователь. Если правило соответствия не найдено, это означает, что пользователь не авторизован. Примечание переводчика: Операции, не перечисленные в разделе только, будут разрешены безоговорочно.
Когда ACF определяет, что пользователь не авторизован для выполнения текущей операции, его обработка по умолчанию:
Если пользователь является посетителем, yii web User:: loginRequired () вызывается для перенаправления браузера пользователя на страницу входа.
Если пользователь является аутентифицированным пользователем, создается исключение yii web ForbiddenHttpException.
Вы можете настроить это поведение, настроив свойство управления доступом к фильтрам yii:: denyCallback:
[
'class' => AccessControl::className(),
...
'denyCallback' => function ($rule, $action) {
throw new \Exception('You are not allowed to access this page');
}
]Правило доступа к фильтрам Yii поддерживает множество опций.
Ниже приведен обзор поддерживаемых параметров: вы можете создать yii filters AccessRule для создания пользовательских классов правил доступа.
* yii filters AccessRule:: allow: Specifies whether the rule is "allowed" or "rejected". (Translator's Note: true is permissible, false is refusal)
* yii filters AccessRule:: actions: Specifies which operations the rule is used to match. Its value should be the ID array of the method of operation. Matching comparison is case sensitive. If this option is empty or not used, it means that the current rule applies to all operations.
1. yii filters AccessRule:: controllers: Specify which controllers the rule is used to match. Its value should be the controller ID array. Matching comparison is case sensitive. If this option is empty or not used, it means that the current rule applies to all operations. (Translator's Note: This option is usually used in the controller's custom parent class to make sense)
2. yii filters AccessRule:: roles: Specify which user roles the rule is used to match. The system has two special roles, which are judged by yii web User:: isGuest:
*?: Used to match visitor users (unauthorized)
*@ Used to match authenticated users
3. When using other role names, the call yii web User:: can () will be triggered, requiring RBAC support (described in the next section). If the option is empty or not used, it means that the rule applies to all roles.
4. yii filters AccessRule:: ips: Specifies which yii web Request:: userIP the rule is used to match. IP addresses can contain wildcards * at the end to match a batch of IP addresses with the same prefix. For example, 192.168. * matches the IP addresses of all 192.168. segments. If the option is empty or not used, it means that the rule applies to all roles.
5. yii filters AccessRule:: verbs: Specify which request method the rule is used to match (e.g. GET, POST). The matching case here is insensitive.
6. yii filters AccessRule:: matchCallback: Specifies a PHP callback function to determine whether the rule meets the criteria. (Translator's Note: The callback function here is an anonymous function)
7. yii filters AccessRule:: denyCallback: Specifies a PHP callback function that is called when the rule does not satisfy the condition. (Translator's Note: The callback function here is an anonymous function)В следующем примере показано, как использовать опцию обратного вызова соответствия, чтобы вы могли разработать логику проверки произвольного доступа:
use yii\filters\AccessControl;
class SiteController extends Controller{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['special-callback'],
'rules' => [
[
'actions' => ['special-callback'],
'allow' => true,
'matchCallback' => function ($rule, $action) {
return date('d-m') === '31-10';
}
],
],
],
];
}
// The matching callback function is called! This page is accessible only on October 31 every year.
public function actionSpecialCallback()
{
return $this->render('happy-halloween');
}
}Управление доступом на основе ролей (RBAC)
Управление доступом на основе ролей (RBAC) обеспечивает простой и мощный механизм централизованного контроля доступа.
Yii реализует общую иерархическую модель RBAC, которая следует модели NIST RBAC. Он предоставляет функции RBAC через компонент приложения интерфейса yii rbac Manager. Использование RBAC включает в себя две части работы. Первая часть заключается в установлении данных авторизации, в то время как вторая часть заключается в использовании этих данных авторизации для выполнения проверок там, где это необходимо. Чтобы облегчить последующее повествование, здесь сначала представим некоторые основные концепции RBAC.
Основные понятия
Роли-это наборы разрешений (например, размещение, изменение). Роль может быть назначена одному или нескольким пользователям. Чтобы проверить, имеет ли пользователь определенные привилегии, система проверяет, назначена ли этому пользователю роль, содержащая эти привилегии.
Вы можете связать правило с ролью или разрешением. Правило представлено фрагментом кода, и выполнение правила выполняется, когда пользователь удовлетворяет роли или разрешению.
Например, право “изменять сообщения” может использовать правило, чтобы проверить, является ли пользователь создателем сообщения. При проверке разрешений, если пользователь не является создателем сообщения, то он или она будет считаться не имеющим разрешения на “изменение сообщения”.
Роли и привилегии могут быть организованы иерархически. В конкретном случае роль может состоять из других ролей или разрешений, а разрешения могут состоять из других разрешений.
Yii реализует так называемую иерархию локального порядка, которая содержит более конкретные древовидные иерархии. Роль может содержать разрешение, но не наоборот. Примечание переводчика: Можно понять, что роли выше , разрешения указаны ниже, а роли не могут отображаться ниже, если разрешения встречаются сверху вниз.
Настройка RBAC
Прежде чем вы начнете определять данные авторизации и выполнять проверки доступа, вам необходимо настроить компонент приложения yiibaseApplication:: AuthManager.
Yii предоставляет два набора менеджеров авторизации: yii rbac Php Manager и yii rbac DBManager. Первый использует PHP-скрипт для хранения данных авторизации, в то время как второй использует базу данных для хранения данных авторизации. Если вашему приложению не требуется много динамического управления ролями и полномочиями, вы можете рассмотреть возможность использования первого.
Используйте PhpManager Следующий код показывает, как настроить AuthManager в файле конфигурации приложения при использовании yiirbacPhpManager:
return [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\PhpManager',
],
// ...
],
];Теперь вы можете получить доступ к AuthManager через Yii:: $app – > AuthManager. По умолчанию yii rbac PhpManager сохраняет данные RBAC в файле в каталоге @app/rbac. Если данные иерархии привилегий изменяются во время выполнения, необходимо убедиться, что процесс веб-сервера имеет права на запись в каталог и файлы в нем.
Использование DBManager
Следующий код показывает, как настроить AuthManager в файле конфигурации приложения при использовании yii rbac DBManager: возврат [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
// ...
],]; DBManager использует четыре таблицы базы данных для хранения своих данных:
Yii rbac DBManager: $таблица элементов: В этой таблице хранятся записи авторизации. Имя таблицы по умолчанию – “auth_item”.
Yii rbac менеджер баз данных:: $itemChildTable: В этой таблице хранятся иерархические отношения для записей авторизации. Имя таблицы по умолчанию – “auth_item_child”.
Yii rbac DBManager:: $таблица назначений: В этой таблице хранится назначение авторизованных записей пользователям. Имя таблицы по умолчанию – “auth_assignment”.
Yii rbac DBManager: $таблица правил: Правила хранения таблиц. Имя таблицы по умолчанию – “auth_rule”.
Прежде чем продолжить, вам необходимо создать эти таблицы в базе данных.
Это можно сделать с помощью файла миграции базы данных, хранящегося в каталоге @yii/rbac/миграции.
yii migrate [email protected]/rbac/migrations
Теперь вы можете получить доступ к AuthManager через Yii:: $app – > AuthManager.
Установление данных авторизации Задачи, связанные со всеми данными авторизации, заключаются в следующем:
Определите роли и полномочия;
Установление взаимосвязи между ролями и полномочиями;
Определите правила;
Правила, касающиеся ролей и привилегий;
Назначьте роли пользователям.
В соответствии с гибкими требованиями авторизации вышеуказанные задачи могут быть выполнены различными способами.
Если ваша иерархия привилегий не меняется и количество пользователей остается постоянным, вы можете создать консольную команду для одновременной инициализации данных авторизации с помощью API, предоставляемого AuthManager:
authManager;
// Add CreatePost permission
$createPost = $auth->createPermission('createPost');
$createPost->description = 'Create a post';
$auth->add($createPost);
// Add "updatePost" permission
$updatePost = $auth->createPermission('updatePost');
$updatePost->description = 'Update post';
$auth->add($updatePost);
// Add the "author" role and grant "createPost" permission
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);
// Add "admin" role and assign "updatePost"
// and "author" permissions
$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $updatePost);
$auth->addChild($admin, $author);
// Assign roles to users. Among them, 1 and 2 are IDS returned by Identity Interface:: getId ().
// This function is usually implemented in your User model.
$auth->assign($author, 2);
$auth->assign($admin, 1);
}
}После выполнения этой команды с помощью Yii rbac/init мы получим иерархию, показанную на следующем рисунке:
Авторы могут создавать новые записи, администраторы могут редактировать записи, и все авторы могут это делать.
Если ваше приложение позволяет пользователям регистрироваться, вам необходимо назначить роль новым пользователям во время регистрации.
Например, в расширенном шаблоне проекта, чтобы сделать всех зарегистрированных пользователей авторами, необходимо изменить метод frontendmodelsSignupForm:: регистрация (), как показано в следующем примере:
public function signup(){
if ($this->validate()) {
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
$user->save(false);
// Add the following three lines of code:
$auth = Yii::$app->authManager;
$authorRole = $auth->getRole('author');
$auth->assign($authorRole, $user->getId());
return $user;
}
return null;
}Для сложных требований к контролю доступа с динамически изменяющимися данными авторизации может потребоваться использовать API, предоставляемый AuthManager, для разработки пользовательских интерфейсов (например, панелей управления).
Правила использования
Как упоминалось ранее, правила добавляют дополнительные ограничения к ролям и привилегиям. Правила являются производными классами правила yii rbac. Он должен реализовать метод yii rbac Rule:: execute ().
В предыдущей созданной нами иерархии авторы не могли редактировать свои собственные публикации. Давайте решим эту проблему. Во-первых, нам нужно правило для проверки подлинности того, что текущий пользователь является автором сообщения:
namespace app\rbac;
use yii\rbac\Rule;
/**
* Check if the authorID matches the user parameter passed in through the parameter
*/class AuthorRule extends Rule{
public $name = 'isAuthor';
/**
*@ Param string | integer $user user user ID.
*@ Param Item $item The role or permission associated with this rule
*@ Param array $params parameters passed to ManagerInterface:: checkAccess ()
*@ return Boolean represents whether the roles or permissions associated with the rule are allowed
*/
public function execute($user, $item, $params)
{
return isset($params['post']) ? $params['post']->createdBy == $user : false;
}
}Приведенное выше правило проверяет, была ли запись создана пользователем$. Мы также создадим специальное разрешение updateOwnPost в предыдущей команде:
$auth = Yii::$app->authManager;
// Adding rules
$rule = new \app\rbac\AuthorRule;$auth->add($rule);
// Add "updateOwnPost" permissions and associate them with rules
$updateOwnPost = $auth->createPermission('updateOwnPost');
$updateOwnPost->description = 'Update own post';
$updateOwnPost->ruleName = $rule->name;
$auth->add($updateOwnPost);
// The "updateOwnPost" privilege will be used by the "updatePost" privilege
$auth->addChild($updateOwnPost, $updatePost);
// Allow "author" to update their posts
$auth->addChild($author, $updateOwnPost);Используйте роли по умолчанию
Роль по умолчанию-это роль, которая неявно назначается всем пользователям. Нет необходимости вызывать метод yii rbac ManagerInterface:: assign () для назначения отображения, и данные авторизации не содержат информации о назначении.
Роль по умолчанию обычно связана с правилом для проверки соответствия роли проверяемому пользователю.
Роли по умолчанию часто используются для приложений, которые установили некоторые отношения назначения ролей. Например, в таблице пользователей приложения есть поле группы, которое представляет, к какой привилегированной группе принадлежит пользователь. Если каждую группу привилегий можно сопоставить с ролями RBAC, вы можете автоматически назначить по одной роли RBAC каждому пользователю по ролям по умолчанию. Давайте на примере покажем, как это сделать.
Предположим, у вас есть поле группы в таблице пользователей, одно для группы администраторов и два для группы авторов. Вы планируете, чтобы две роли RBAC “администратор” и “автор” соответствовали разрешениям двух групп соответственно. Вы можете настроить данные RBAC следующим образом.
namespace app\rbac;
use Yii;
use yii\rbac\Rule;
/**
* Check whether the group matches the user
*/class UserGroupRule extends Rule{
public $name = 'userGroup';
public function execute($user, $item, $params)
{
if (!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->group;
if ($item->name === 'admin') {
return $group == 1;
} elseif ($item->name === 'author') {
return $group == 1 || $group == 2;
}
}
return false;
}
}
$auth = Yii::$app->authManager;
$rule = new \app\rbac\UserGroupRule;
$auth->add($rule);
$author = $auth->createRole('author');
$author->ruleName = $rule->name;
$auth->add($author);
//... Add the subitem code of the $author role... (Translator's Note: omit the part referring to the previous console command)
$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
$auth->addChild($admin, $author);
//... Add the subitem code of the $admin role... (Translator's Note: omit the part referring to the previous console command)Обратите внимание, что в приведенном выше коде, поскольку “автор” является подролью “администратор”, при реализации метода execute () этого правила вам также необходимо следовать этой иерархии.
This is why when the role name is "author", the execute () method returns true when the group is 1 or 2 (meaning that the user belongs to the "admin" or "author" group).
Затем при настройке AuthManager укажите параметр yii rbac Base Manager: $Роли по умолчанию.
return [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\PhpManager',
'defaultRoles' => ['admin', 'author'],
],
// ...
],
];Now if you perform an access check, both admin and author roles will check when deciding on the rule. If the rule returns true, it means that the role matches the current user. Based on the implementation of the above rules, it means that if a user's group value is 1, the admin role will be assigned to that user, and if the group value is 2, the author role will be given.
Пароли
Стратегии продовольственной безопасности имеют решающее значение для здоровья и успеха любого применения.
К сожалению, многие разработчики не обращают особого внимания на детали, когда сталкиваются с проблемами безопасности, потому что они недостаточно знают или их трудно реализовать.
Чтобы сделать ваше приложение Yii максимально безопасным, Yii включает в себя несколько превосходных и простых в использовании функций безопасности.
Хэширование и проверка паролей
Большинство разработчиков знают, что пароли нельзя хранить в виде открытого текста, но многие по-прежнему считают, что использование MD5 или SHA1 для хэширования паролей безопасно.
В свое время описанный выше алгоритм хэширования был достаточно безопасным, но развитие современного оборудования позволило за короткое время насильственно взломать строку хэша, сгенерированную описанным выше алгоритмом.
Чтобы обеспечить повышенную безопасность паролей пользователей даже в худшем случае (ваше приложение было взломано), вам необходимо использовать алгоритм хэширования, который может противостоять жестоким атакам взлома. В настоящее время лучшим выбором является bcrypt.
В PHP вы можете генерировать хэш bcrypt с помощью функции crypt. Yii предоставляет две вспомогательные функции, упрощающие использование crypt для генерации и проверки безопасного хэш-пароля.
Когда пользователь вводит пароль для первого использования (например, для регистрации), пароль необходимо хэшировать. $хэш::$приложение->getSecurity()->generatePasswordHash($пароль);
Хэш-строки могут быть связаны с соответствующими атрибутами модели, чтобы их можно было сохранить в базе данных для дальнейшего использования.
Когда пользователь пытается войти в систему, пароль, отправленный формой, должен быть проверен с использованием ранее сохраненной хэш-строки:
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
// all good, logging user in
} else {
// wrong password
}Генерация Псевдослучайных чисел
Псевдослучайные данные очень полезны во многих сценариях.
Например, при сбросе пароля по почте вам необходимо сгенерировать токен, сохранить его в базе данных и отправить конечному пользователю по почте, чтобы подтвердить его право собственности на учетную запись.
Уникальность и загадочность этого токена очень важны. В противном случае существует вероятность того, что злоумышленник сможет угадать токен и сбросить пароль пользователя.
Помощник по безопасности Yii позволяет очень просто генерировать псевдослучайные данные:
$key = Yii::$app->getSecurity()->generateRandomString();
Обратите внимание, что вам необходимо установить расширения OpenSSL для создания безопасных случайных данных для паролей.
шифрование и дешифрование
Yii предоставляет удобную справочную функцию, позволяющую шифровать и расшифровывать данные с помощью безопасного секретного ключа. Данные передаются с помощью функции шифрования, так что расшифровать их могут только те, у кого есть ключ безопасности.
Например, нам нужно сохранить некоторую информацию в нашей базе данных, но нам нужно убедиться, что ее могут видеть только те, у кого есть ключ безопасности (даже в случае утечки базы данных приложения).
// $data and $secretKey are obtained from the form $encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey); // store $encryptedData to database
Впоследствии, когда пользователю потребуется прочитать данные:
// $secretKey is obtained from user input, $encryptedData is from the database $data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey);
Проверьте целостность данных
Иногда вам необходимо убедиться, что ваши данные не были изменены третьей стороной или каким-либо образом повреждены. Yii предоставляет простой способ проверки целостности данных с помощью двух справочных функций.
Во-первых, хэш-строка, сгенерированная ключом безопасности и данными, добавляется к данным с префиксом.
// $secretKey our application or user secret, $genuineData obtained from a reliable source $data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey);
Убедитесь, что целостность данных была нарушена.
// $secretKey our application or user secret, $data obtained from an unreliable source $data = Yii::$app->getSecurity()->validateData($data, $secretKey);
Вы также можете установить его свойство enableCsrfValidation для контроллера или действия, чтобы отключить проверку CSRF отдельно.
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller{
public $enableCsrfValidation = false;
public function actionIndex()
{
// CSRF validation will not be applied to this and other actions
}
}Чтобы отключить проверку CSRF для настраиваемого действия, вы можете:
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller{
public function beforeAction($action)
{
// ...set `$this->enableCsrfValidation` here based on some conditions...
// call parent method that will check CSRF if such property is true.
return parent::beforeAction($action);
}
}Некоторые Лучшие Практики
У всех нас есть два основных принципа безопасности, независимо от того, какое приложение мы разрабатываем.
Фильтрация входных данных
экранирование выходных данных
Фильтрация входных данных
Фильтрация ввода означает, что пользовательский ввод не следует считать безопасным, вам всегда нужно проверять, что полученное вами входное значение находится в допустимом диапазоне.
Например, предположим, что сортировка может быть задана только тремя значениями: заголовок, create_at и статус. Затем значение вводится пользователем. Лучше проверить, находится ли значение в указанном диапазоне, когда мы получаем параметры.
Для базового PHP описанный выше подход аналогичен следующему:
$sortBy = $_GET['sort'];
if (!in_array($sortBy, ['title', 'created_at', 'status'])) {
throw new Exception('Invalid sort value.');
}В Yii существует большая вероятность того, что вы будете использовать валидаторы форм для выполнения аналогичных проверок.
экранирование выходных данных
Вывод escape означает, что данные должны быть экранированы в соответствии с контекстом, в котором мы их используем.
Например, в контексте HTML вам нужно экранировать специальные символы, такие как <,>. В JavaScript или SQL строки с другими специальными значениями должны быть экранированы.
Поскольку ручное экранирование используемых выходных данных может привести к ошибкам, Yii предоставляет ряд инструментов для выполнения экранирования в различных контекстах.
Избегайте внедрения SQL
Внедрение SQL происходит, когда оператор запроса создается из строки, которая не экранируется соединением, например:
$username = $_GET['username']; $sql = "SELECT * FROM user WHERE username = '$username'";
В дополнение к правильному имени пользователя злоумышленник может ввести в ваше приложение такие инструкции, как”; УДАЛИТЬ пользователя ТАБЛИЦЫ;–”. Это приведет к созданию следующего SQL:
SELECT * FROM user WHERE username = ''; DROP TABLE user; --'
Это допустимая инструкция запроса, которая выполнит поиск пользователей с пустыми именами пользователей, а затем удалит таблицу пользователей. Это может привести к перемещению веб-сайта и потере данных. У вас есть регулярные резервные копии данных?
В Yii большинство запросов данных выполняются через Активную запись, и они полностью выполняются с использованием инструкций предварительной обработки PDO для выполнения SQL-запросов. В инструкции предварительной обработки сценарий построения SQL-запроса в приведенном выше примере невозможен.
Иногда вам все еще нужно использовать необработанные запросы или построители запросов. В этом случае вы должны передавать параметры безопасным способом. Если данные представляют собой значение, указанное в столбце таблицы, лучше использовать инструкцию предварительной обработки:
// query builder
$userIDs = (new Query())
->select('id')
->from('user')
->where('status=:status', [':status' => $status])
->all();
// DAO
$userIDs = $connection
->createCommand('SELECT id FROM user where status=:status')
->bindValues([':status' => $status])
->queryColumn();Если данные используются для указания имен столбцов или таблиц, лучший способ-разрешить только предопределенные значения перечисления.
function actionList($orderBy = null){
if (!in_array($orderBy, ['name', 'status'])) {
throw new BadRequestHttpException('Only name and status are allowed to order by.')
}
// ...
}Если описанный выше метод не работает, имена таблиц или столбцов следует экранировать. Yii предоставляет специальную грамматику для этого экранирования, чтобы решение можно было использовать во всех поддерживаемых базах данных.
$sql = "SELECT COUNT($column) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();Предотвращение XSS-атак
XSS или межсайтовые сценарии возникают, когда HTML экспортируется в браузер, и выводимое содержимое не экранируется должным образом.
For example, if a user can enter his name, he enters < script > alert ('Hello!'); instead of his name Alexander, all pages that output a user name without escape will execute the JavaScript code alert ('Hello!'); this will cause a warning pop-up box on the browser page.Для определенных сайтов, в дополнение к этому бессмысленному выводу предупреждений, такие сценарии могут отправлять некоторые сообщения в фоновом режиме от вашего имени или даже выполнять некоторые банковские транзакции.
Избежать атак XSS в Yii очень просто. Есть две общие ситуации:
Вы хотите, чтобы данные выводились в виде обычного текста.
Вы хотите, чтобы данные выводились в формате HTML.
Если вам нужен обычный текст, вы можете просто избежать его следующим образом:
= \yii\helpers\Html::encode($username) ?>
Если это HTML, мы можем использовать справочный класс HTMLPurifier для выполнения:
= \yii\helpers\HtmlPurifier::process($description) ?>
Примечание: Обработка класса справки HTMLPurifier занимает много времени. Рекомендуется добавить кэширование:
Предотвращение атак CSRF CSRF-это сокращение от подделки межстанционных запросов. Идея этой атаки проистекает из предположения, что запросы браузера от пользователей генерируются самими пользователями, чего нет во многих приложениях.
Например, an.example.com на сайте есть URL-адрес/выхода, который выводит пользователей из системы при запросе доступа с помощью GET. Если им управляет сам пользователь, то все в порядке. Однако однажды плохой человек опубликовал форум, который часто посещали пользователи.
Публикации контента. Браузер не может определить, запрашивать ли изображение или страницу, поэтому, когда пользователь открывает страницу с указанным выше тегом, он выйдет из. example. ком.
Выше приведена самая примитивная мысль. Некоторые люди могут сказать, что пользователи, вышедшие из системы, не являются серьезной проблемой, однако отправка некоторых почтовых данных на самом деле не очень хлопотная вещь.
Чтобы избежать атак CSRF, вам всегда нужно:
Следуя рекомендациям HTTP, таким как GET, не следует изменять состояние приложения.
Убедитесь, что включена защита Yii CSRF.
Предотвращение раскрытия документов
Каталог веб-корня сервера по умолчанию указывает на веб-каталог, содержащий индекс. php.
В среде общего хостинга это невозможно, в результате чего весь код, конфигурация и журналы находятся в каталоге Webroot.
Если это так, не забудьте запретить доступ к каталогам, отличным от веб-каталогов. Если это невозможно, рассмотрите возможность размещения вашего приложения в другом месте.
Отключите отладочную информацию и инструменты в производственных средах
В режиме отладки Yii показывает много информации об ошибках, которая полезна для разработки. Аналогично, эта отладочная информация удобна злоумышленникам для взлома структур данных, значений конфигурации и некоторых элементов вашего кода.
Никогда не устанавливайте YII_DEBUG в своем индексе. PHP в значение true в рабочем режиме.
Вы также не должны включать Gii в производственном режиме.
Его можно использовать для получения информации о структуре данных, кода и простой перезаписи вашего кода кодом, сгенерированным Gii.
Панели инструментов отладки также следует избегать в производственных средах, если в этом нет необходимости. В нем будут представлены подробные сведения обо всех приложениях и конфигурациях. Если вы уверены, что вам это нужно, повторно подтвердите, что его доступ ограничен вашим собственным IP-адресом.
Оригинал: “https://developpaper.com/the-way-of-yiis-practice-security-security/”