Yii PHP framework: создаём игровой сайт. Часть 3. Аутентификация.

Владимир | | PHP, Web разработка, Yii.

yii_game_site_auth

Приветствую всех! Эта статья – продолжение цикла о создании игрового сайта с использованием PHP фреймворка Yii.

Сегодня мы займемся ограничением доступа к административной части сайта. У вас может возникнуть вполне закономерный вопрос: «Почему именно ею? Ведь в предыдущих частях мы только создали базу данных, на сайте нет ни одной рабочей страницы.»

Всё правильно, но Yii имеет некоторые особенности. Код, который генерирует консольная утилита при создании контроллеров, автоматически использует встроенную библиотеку авторизации. Кроме того, в стандартном приложении, которое мы в прошлый раз создали командой yiic webapp есть все необходимые компоненты для аутентификации и авторизации пользователей.

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

Прежде всего, рассмотрим как вообще работает эта библиотека.

Основная её часть – это компонент реализующий интерфейс IWebUser. Доступ к нему можно получить так:

Yii::app()->user

Используя этот компонент (экземпляр класса СWebUser) можно проверить выполнил ли пользователь вход, получить его данные и т.п.

Для того, чтобы аутентифицировать пользователя мы должны определить класс, в котором будет находится код, проверяющий имя и пароль. Этот класс уже создан и находится он в файле protected\components\UserIdentity.php, но по-умолчанию имя и пароль записаны в обычном массиве, а нам нужно хранить их в базе данных.

Поэтому мы перепишем метод authenticate.

public function authenticate()
{
	//ищем пользователя по имени
	$record=Users::model()->findByAttributes(array('u_login'=>$this->username));
	//если пользователь найден и его пароль совпадает с введенным...
	if($record===null)
		$this->errorCode=self::ERROR_USERNAME_INVALID;
	else if($record->u_password!==md5($this->password))
		$this->errorCode=self::ERROR_PASSWORD_INVALID;
	else
	{
		//...сохраняем данные пользователя (имя и адрес фида)
		// (в принципе, адрес фида можно не сохранять, тогда при импорте игр
		// нужно будет выполнить дополнительный запрос)
		$this->_id=$record->u_id;
		$this->setState('name', $record->u_name);
		$this->setState('xml', $record->u_xml);
		$this->errorCode=self::ERROR_NONE;
	}
	return !$this->errorCode;
}

За основу я взял код из примера на официальном сайте, но немного его изменил.

Прежде всего, обратите внимание на строку 4. В ней мы ищем пользователя в базе данных. При этом используется класс модели Users, которую мы чуть позже создадим. Метод findByAttributes предназначен для поиска по заданным полям таблицы в БД. В качестве параметра этому методу мы передаем массив, в котором ключ элемента (u_login) соответствует названию поля, а его значение – значению, которое мы хотим найти.

Затем мы проверяем имя и пароль и, если проверка пройдена, сохраняем данные пользователя. Я решил сохранить имя пользователя и адрес его xml фида.

Теперь мы можем легко получить эти данные. Например,

Yii::app()->user->xml

Если бы мы их не сохранили, то пришлось бы выполнять запрос к БД.

Создадим модель Users.

Прежде всего, укажем параметры подключения к БД в файле конфигурации protected\config\main.php.

'db'=>array(
	'connectionString'=>'mysql:host=localhost;dbname=имя_бд',
	'username'=>'имя_пользователя',
	'password'=>'пароль',
	'charset'=>'utf8',
),

И выполняем в консоли две команды.

>> yiic shell
>> model Users ygs_users

После этого у нас появится файл protected\models\Users.php.

Тут же мы можем создать стандартный код для выполнения CRUD операций

>> crud Users

В результате появятся контроллер (protected\controllers\UsersController.php) и папка с файлами представлений (protected\views\users\). Сейчас мы их трогать не будем, они понадобятся в дальнейшем, когда мы будем заниматься админкой сайта.

А сейчас создадим ещё один контроллер.

>> controller Dashboard

Это не обязательно, но я не хочу чтобы форма входа относилась к контроллеру SiteController, который был создан по-умолчанию.

Перенесем форму входа в контроллер Dashboard, и заодно разберем каким образом выполняется аутентификация и авторизация пользователей.

Сама форма находится в файле protected\views\site\login.php. Поэтому просто перемещаем его в папку protected\views\dashboard\.

Настраиваем контроллер Dashboard.

Добавляем метод (на самом деле вручную писать код не нужно, можно просто скопировать метод из файла SiteController.php)

public function filters()
{
	return array(
		'accessControl', // perform access control for CRUD operations
	);
}

Теперь перед обращением к любому из методов контроллера фреймворк будет проверять имеет ли посетитель достаточные права.

Добавляем метод

public function accessRules()
{
	return array(
		array('allow',
			'actions'=>array('login','logout'),
			'users'=>array('*'),
		),
		array('allow',
			'actions'=>array('index'),
			'users'=>array('admin'),
		),
		array('deny',  // deny all users
			'users'=>array('*'),
		),
	);
}

В нём находится массив с правилами, которые указывают, что общедоступными являются только методы actionLogin() и actionLogout(). Первый показывает форму входа, второй – выполняет выход из системы.

Копируем и эти два метода

/**
 * Формирует страницу с формой входа
 */
public function actionLogin()
{
	$form=new LoginForm;
	// collect user input data
	if(isset($_POST['LoginForm']))
	{
		$form->attributes=$_POST['LoginForm'];
		// validate user input and redirect to previous page if valid
		if($form->validate())
			$this->redirect(Yii::app()->user->returnUrl);
	}
	// display the login form
	$this->render('login',array('form'=>$form));
}

/**
 * Выход из панели управления и переход на главную страницу.
 */
public function actionLogout()
{
	Yii::app()->user->logout();
	$this->redirect(Yii::app()->homeUrl);
}

С методом actionLogout(), надеюсь, всё понятно. Сначала завершаем сессию (метод logout()), затем отправляем редирект на домашнюю страницу.

Метод actionLogin() немного сложнее. Здесь мы создаём объект типа LoginForm. Класс LoginForm создан автоматически и находится в файле (protected\models\LoginForm.php).

Этот класс содержит метод authenticate, который вызывается для проверки поля с паролем. И именно в этом методе создаётся объект типа UserIdentity, который содержит нашу логику проверки имени и пароля. В этом же методе находится вызов Yii::app()->user->login(…).

Подводя итог, запишем порядок аутентификации.

1) Посетитель вводит имя / пароль и нажимает кнопку «Войти».

2) Фреймворк создает DashboardController и вызывает его метод actionLogin.

3) В методе actionLogin создается экземпляр класса LoginForm и вызывается его метод validate.

4) Фреймворк перебирает все правила, указанные в массиве, который возвращает метод rules. Одно из этих правил выглядит так
array('password', 'authenticate')
Это означает, что должен быть вызван метод LoginForm::authenticate(…).

5) LoginForm:: authenticate(…) создаёт экземпляр класса UserIdentity и вызывает его метод authenticate (в котором находится наша логика проверки имени и пароля).

6) Если все проверки прошли успешно, вызывается Yii::app()->user->login(…). Аутентификация завершена.

На первый взгляд, выглядит немного запутанно, но это потому, что используется несколько библиотек фреймворка одновременно. В частности, используется библиотека для проверки данных форм.

Тут я хочу отметить одно из отличий Yii от CodeIgniter. В состав Yii входит довольно много библиотек, и генератор кода их активно использует. Поэтому если библиотеки вас устраивают, вы выигрываете, т.к. значительная часть кода будет написана за вас. С другой стороны, если вы хотите использовать другую библиотеку, то эту часть кода придется переписать.

В следующей части мы рассмотрим работу с жанрами игр.

Все разделы цикла.

  1. Yii PHP framework: создаём игровой сайт. Часть 1. Постановка задачи.
  2. Yii PHP framework: создаём игровой сайт. Часть 2. База данных и установка фреймворка.
  3. Yii PHP framework: создаём игровой сайт. Часть 3. Аутентификация.
  4. Yii PHP framework: создаём игровой сайт. Часть 4. Работа с жанрами игр.
  5. Yii PHP framework: создаём игровой сайт. Часть 5. Импорт игр.
  6. Yii PHP framework: создаём игровой сайт. Часть 6. Формируем страницы игр и жанров.
  7. Yii PHP framework: создаём игровой сайт. Часть 7. Работа с JavaScript и страницы игр.
  8. Yii PHP framework: создаём игровой сайт. Часть 8. Создаём виджеты.
  9. Yii PHP framework: создаём игровой сайт. Часть 9. Поиск ошибок.
  10. Yii PHP framework: создаём игровой сайт. Часть 10. Панель управления.
  11. Yii PHP framework: создаём игровой сайт. Часть 11. Человекопонятные URL.
  12. Архив с исходниками

Постовой

Рекомендуем: абонентское кадровое обслуживание ООО и ИП. От профессионалов