Настройка
Laravel стремится сделать реализацию авторизации максимально простой. Фактически, почти всё уже настроено после установки. Настройки хранятся в файле app/config/auth.php, который содержит несколько хорошо документированных параметров для настройки поведения методов авторизации.
По умолчанию Laravel включает в себя модель PHPUser
в папке app/models, которая может использоваться вместе с драйвером авторизации Eloquent (по умолчанию). При создании таблицы для данной модели убедитесь, что поле пароля принимает как минимум 0 символов.
Если ваше приложение не использует Eloquent, вы можете использовать драйвер database, который использует конструктор запросов Laravel.
Прежде чем начать, убедитесь, что в вашей таблице users (или её эквиваленте) есть обнуляемое строковое поле на 100 символов. В этом поле будет храниться ключ для сессий «запомнить меня», поддерживаемых вашим приложением. Это можно сделать с помощью PHP$table->rememberToken();
в миграции.
Хранение паролей
Класс PHPHash
содержит методы для безопасного хэширования с помощью Bcrypt.
Хэширование пароля по алгоритму Bcrypt
$password = Hash::make('secret');
if (Hash::check('secret', $hashedPassword)) {
// Пароль подходит...
}
Проверка на необходимость перехэширования пароля
if (Hash::needsRehash($hashed)) {
$hashed = Hash::make('secret');
}
Авторизация пользователей
Для авторизации пользователя в вашем приложении используется метод PHPAuth::attempt()
:
if (Auth::attempt(array('email' => $email, 'password' => $password))) {
return Redirect::intended('dashboard');
}
Заметьте, что поле email не обязательно и оно используется только для примера. Вы должны использовать любое поле, которое соответствует имени пользователя в вашей БД. Метод PHPRedirect::intended()
отправит пользователя на URL, который он пытался просмотреть до того, как запрос был перехвачен фильтром авторизации. Дополнительный URL может быть передан в метод, если требуемый адрес не доступен.
Когда вызывается метод PHPAuth::attempt()
возбуждается событие auth.attempt. При успешной авторизации также произойдёт событие auth.login.
Проверка авторизации пользователя
Для определения того, авторизован ли пользователь или нет, можно использовать метод PHPAuth::check()
:
if (Auth::check()) {
// Пользователь уже вошёл в систему...
}
Авторизация и запоминание пользователя
Если вы хотите предоставить функциональность типа «запомнить меня», то вы можете передать PHPtrue
вторым параметром к методу PHPAuth::attempt()
, который будет поддерживать авторизацию пользователя без ограничения по времени (пока он вручную не выйдет из системы). Разумеется, ваша таблица users должна содержать строковое поле remember_token для хранения ключа сессий «запомнить меня».
if (Auth::attempt(array('email' => $email, 'password' => $password), true)) {
// Пользователь был запомнен...
}
Внимание: если метод PHPAuth::attempt()
вернул PHPtrue
, то пользователь успешно вошёл в систему.
добавлено в 4.1 ()
Авторизация пользователя с условиями
Вы также можете передать дополнительные условия для запроса к таблице:
if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1))) {
// Вход, если пользователь активен, не отключен и существует.
}
Для дополнительной защиты от фиксации сессии, ID сессии пользователя будет автоматически сгенерирован заново после авторизации.
Доступ к авторизованному пользователю
Как только пользователь авторизован вы можете обращаться к модели PHPUser
и её свойствам:
$email = Auth::user()->email;
добавлено в 4.2 ()
Для простой авторизации пользователя по ID используется метод PHPloginUsingId()
:
Auth::loginUsingId(1);
Проверка данных для входа без авторизации
Метод PHPvalidate()
позволяет вам проверить данные для входа без осуществления самого входа:
if (Auth::validate($credentials)) {
//
}
Авторизация пользователя на один запрос
Вы также можете использовать метод PHPonce()
для авторизации пользователя в системе только для одного запроса. Сессии и cookies не будут использованы.
if (Auth::once($credentials)) {
//
}
Auth::logout();
Ручная авторизация
Если вам нужно авторизовать существующего пользователя просто передайте его модель в метод PHPAuth::login()
:
$user = User::find(1);
Auth::login($user);
Это эквивалентно авторизации пользователя через его данные методом PHPAuth::attempt()
.
Защита маршрутов
Вы можете использовать Фильтры маршрутов, чтобы позволить только авторизованным пользователям обращаться к данному маршруту. Изначально Laravel содержит фильтр auth, который содержится в файле app/filters.php.
Route::get('profile', array('before' => 'auth', function () {
// Доступно только авторизованным пользователям...
}));
Защита от подделки запросов (CSRF)
Laravel предоставляет простой способ защиты вашего приложения от подделки межсайтовых запросов (CSRF).
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
Проверка переданного CSRF-ключа
Route::post('register', array('before' => 'csrf', function() {
return 'Вы передали верный ключ!';
}));
Простая HTTP-авторизация
HTTP Basic Authentication — простой и быстрый способ авторизовать пользователей вашего приложения без создания дополнительной страницы входа. Для начала подключите фильтр auth.basic.
Защита маршрута фильтром HTTP-авторизации
Route::get('profile', array('before' => 'auth.basic', function () {
// Доступно только авторизованным пользователям...
}));
По умолчанию, фильтр basic будет использовать поле PHP$email
модели объекта при авторизации. Если вы хотите использовать иное поле, можно передать его имя первым параметром методу PHPbasic()
в вашем файле app/filters.php:
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
Авторизация без запоминания состояния
Вы можете использовать HTTP-авторизацию без установки cookie в сессии, что особенно удобно для авторизации в API. Для того, чтобы сделать это, зарегистрируйте фильтр, возвращающий результат вызова PHPAuth::onceBasic()
:
Route::filter('basic.once', function () {
return Auth::onceBasic();
});
Если вы используете PHP FastCGI, то по умолчанию простая HTTP-аутентификация не будет работать правильно. В файл .htaccess надо добавить следующие строки:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Сброс и изменение паролей
Модель и таблица
Большая часть приложений позволяют пользователям сбрасывать свои забытые пароли. Вместо того, чтобы заставлять вас реализовывать эту функциональность в каждом приложении, Laravel предоставляет удобный способ для отправки писем о сбросе пароля и выполнения самого сброса. Для начала убедитесь, что модель PHPUser
реализует интерфейс PHPIlluminate\Auth\Reminders\RemindableInterface
. Это уже сделано для модели PHPUser
, включённой в фреймворк по умолчанию.
В Laravel 4.2 эта модель использует PHPIlluminate\Auth\Reminders\RemindableTrait
для включения методов, необходимых для реализации интерфейса. — прим. пер.
Реализация интерфейса PHPRemindableInterface
добавлено в 4.2 ()
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements RemindableInterface {
use RemindableTrait;
}
добавлено в 4.1 ()
class User extends Eloquent implements RemindableInterface {
public function getReminderEmail()
{
return $this->email;
}
}
Генерация миграции для таблиц сброса паролей
Затем вам нужно создать таблицу для хранения ключей сброса паролей. Для создания миграции для таблицы просто выполните команду auth:reminders-table интерфейса Artisan.
shphp artisan auth:reminders-table php artisan migrate
добавлено в 4.1 ()
Контроллер сброса паролей
Теперь мы готовы к созданию контроллера сброса паролей. Чтобы автоматически создать контроллер, вы можете использовать Artisan-команду shauth:reminders-controller
, которая создаст файл RemindersController.php в вашем каталоге app/controllers.
shphp artisan auth:reminders-controller
В созданном контроллере уже будет метод PHPgetRemind()
, который обрабатывает отображение вашей формы сброса пароля. Вам надо только создать шаблон password.remind. В этом шаблоне должна быть основная форма с полем email. Форма должна отправлять POST-запрос в действие RemindersController@postRemind.
Простая форма в шаблоне password.remind может выглядеть так:
<form action="{{ action('RemindersController@postRemind') }}" method="POST">
<input type="email" name="email">
<input type="submit" value="Send Reminder">
</form>
В дополнение к PHPgetRemind()
в созданном контроллере будет метод PHPpostRemind()
, который обрабатывает отправку оповещений о сбросе пароля вашим пользователям по электронной почте. Этот метод предполагает наличие поля email в переменных POST. Если оповещение будет успешно отправлено пользователю по электронной почте, то в сессию будет передано сообщение status. Если оповещение не пройдёт, в сессию будет передано сообщение error.
В методе контроллера PHPpostRemind()
вы можете изменить экземпляр сообщения перед его отправкой пользователю:
Password::remind(Input::only('email'), function($message)
{
$message->subject('Password Reminder');
});
Ваш пользователь получит по электронной почте ссылку, которая указывает на метод контроллера PHPgetReset()
. Ключ сброса пароля, который используется для идентификации данной попытки сброса пароля, также будет передан методу контроллера. Действие уже настроено, чтобы вернуть шаблон password.reset, который вы должны создать. Ключ token будет передан в шаблон, и вы должны поместить этот ключ в скрытое поле формы token. Кроме поля token форма сброса пароля должна содержать поля email, password и password_confirmation. Форма должна отправлять POST-запрос в метод PHPRemindersController@postReset
.
Простая форма в шаблоне password.reset может выглядеть так:
<form action="{{ action('RemindersController@postReset') }}" method="POST">
<input type="hidden" name="token" value="{{ $token }}">
<input type="email" name="email">
<input type="password" name="password">
<input type="password" name="password_confirmation">
<input type="submit" value="Reset Password">
</form>
Наконец, метод PHPpostReset()
отвечает за фактическое изменение пароля в хранилище. В этом действии контроллера замыкание, переданное в метод PHPPassword::reset()
, устанавливает атрибут password для user и вызывает метод PHPsave
. Конечно, это замыкание предполагает, что ваша модель user является моделью Eloquent. Однако вы можете изменить это замыкание по мере необходимости, чтобы оно было совместимым с системой хранения базы данных вашего приложения.
Если пароль успешно сброшен, пользователь будет перенаправлен в корень вашего приложения. Опять же, вы можете изменить URL этого перенаправления. Если сброс пароля не пройдёт, пользователь будет перенаправлен обратно в форму сброса, и в сессию будет передано сообщение error.
Проверка пароля
По умолчанию метод PHPPassword::reset()
будет проверять, что пароли совпадают и содержат не менее шести символов. Вы можете настроить эти правила, используя метод PHPPassword::validator()
, который принимает замыкание. В этом замыкании, вы можете делать любые проверки пароля. Обратите внимание, что вам не надо проверять совпадение паролей, фреймворк сделает это автоматически.
Password::validator(function($credentials)
{
return strlen($credentials['password']) >= 6;
});
По умолчанию ключи сброса пароля истекают через один час. Вы можете изменить это с помощью параметра reminder.expire в вашем файле app/config/auth.php.
добавлено в 4.0 ()
Раздел применим только к версии Laravel 4.0.
Отправка уведомления о сбросе пароля
Для отправки уведомления вы можете использовать метод PHPPassword::remind()
:
Route::post('password/remind', function ()
{
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'password_confirmation' => Input::get('password_confirmation')
);
return Password::remind($credentials);
});
Заметьте, что параметры, переданные в метод PHPPassword::remind()
, похожи на те, которые передаются методу PHPAuth::attempt()
. Этот метод получит модель PHPUser
и отправит соответствующее письмо со ссылкой для сброса. В шаблон письма будет передана переменная PHP$token
, которая может быть использована для изменения пароля через форму его сброса. Кроме неё будет также передана переменная PHP$user
.
Внимание: вы можете указать, какой шаблон должен использоваться при создании сообщения, изменив настройку приложения auth.reminder.email. Изначально фреймворк уже содержит нужный шаблон.
Вы можете изменить объект письма, которое отправляется пользователю, передав замыкание в виде второго аргумента методу PHPPassword::remind()
:
return Password::remind($credentials, function ($message, $user) {
$message->subject('Ваше уведомление о сбросе.');
});
Как вы можете заметить, в маршруте мы напрямую возвращаем результат вызова метода PHPPassword::remind()
. По умолчанию этот метод возвращает переадресацию на текущий адрес, если возникла ошибка при сбросе пароля, при этом устанавливается одноразовая переменная error, а также reason, которая используется для извлечения языковой строки из языкового файла reminders. Если пароль был успешно сброшен, то будет установлена одноразовая переменная success. Таким образом, шаблон для формы сброса пароля должен выглядеть примерно так:
@if (Session::has('error'))
{{ trans(Session::get('reason')) }}
@elseif (Session::has('success'))
На ваш e-mail было отправлено письмо с инструкциями о сбросе пароля.
@endif
<input type="text" name="email">
<input type="submit" value="Отправить письмо">
Сброс пароля (4.0)
Как только пользователь перешёл по ссылке в письме, он будет перенаправлен на форму со скрытым ключом token, а также полями password и password_confirmation. Ниже — пример маршрута для формы сброса:
Route::get('password/reset/{token}', function ($token) {
return View::make('auth.reset')->with('token', $token);
});
А сама форма может выглядеть так:
@if (Session::has('error'))
{{ trans(Session::get('reason')) }}
@endif
<input type="hidden" name="token" value="{{ $token }}">
<input type="text" name="email">
<input type="password" name="password">
<input type="password" name="password_confirmation">
Обратите внимание, что мы снова используем сессии для отображения ошибки, которая могла произойти при сбросе пароля. Дальше мы определяем POST-маршрут, который и произведёт сброс:
Route::post('password/reset/{token}', function () {
$credentials = array('email' => Input::get('email'));
return Password::reset($credentials, function ($user, $password) {
$user->password = Hash::make($password);
$user->save();
return Redirect::to('home');
});
});
При успешном сбросе объект PHPUser
и пароль будут переданы в замыкание, что позволит вам сохранить изменённую модель. После этого вы можете вернуть объект PHPRedirect
или любой другой тип ответа, что и будет возвращено методом PHPPassword::reset()
. Заметьте, что этот метод автоматически проверяет переданный ключ (token), данные для входа и совпадение введённых паролей.
По умолчанию время действия ключа для сброса пароля — час. Вы можете настроить это время с помощью параметра reminder.expire в вашем файле app/config/auth.php.
Также, по аналогии с методом PHPPassword::remind()
, если во время сброса произошла ошибка метод PHPPassword::reset()
вернёт объект PHPRedirect
на текущий адрес с одноразовыми переменными error и reason.
Шифрование
Laravel предоставляет функции для устойчивого шифрования по алгоритму AES с помощью расширения mcrypt для PHP.
$encrypted = Crypt::encrypt('секрет');
Внимание: версия 4.2 перешла на 128-битный AES, а 4.1 и ниже использовала 256-битный. Это значит, что преждезакодированные значения после обновления раскодировать не получится — см. руководство по обновлению — прим. пер.
Внимание: обязательно установите 16, 24 или 32-значный ключ key (до версии 4.2 — только 32-значный — прим. пер.) в файле app/config/app.php. Если этого не сделать, зашифрованные строки не будут безопасными.
$decrypted = Crypt::decrypt($encryptedValue);
Изменение алгоритма и режима шифрования
Crypt::setMode('ctr');
Crypt::setCipher($cipher);
добавлено в 4.1 ()
Драйверы авторизации
Laravel предоставляет драйверы авторизации database и eloquent прямо из коробки. Для получения дополнительной информации о добавлении дополнительных драйверов авторизации прочитайте документации по расширению авторизации.
Комментарии (1)
Насколько же просто реализовано восстановление пароля пользователем