{{TOC}} {{DOCVER 4.0=0da300f6445bec5a70d007f503834fce957b065b 16.10.2014 5:19:26, 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03, 4.2=d7b13440c003218ed79e9d508706eca01990122f 4.12.2014 5:01:15}} == Настройка == Laravel стремится сделать реализацию авторизации максимально простой. Фактически, почти всё уже настроено после установки. Настройки хранятся в файле %%(t)app/config/auth.php%%, который содержит несколько хорошо документированных параметров для настройки поведения методов авторизации. По умолчанию Laravel включает в себя модель %%User%% в папке %%(t)app/models%%, которая может использоваться вместе с драйвером авторизации Eloquent (по умолчанию). При создании ((docs/v4/schema таблицы)) для данной модели убедитесь, что поле пароля принимает как минимум 0 символов. Если ваше приложение не использует Eloquent, вы можете использовать драйвер %%(t)database%%, который использует ((docs/v4/queries конструктор запросов)) Laravel. .(alert) Прежде чем начать, убедитесь, что в вашей таблице %%(t)users%% (или её эквиваленте) есть обнуляемое строковое поле на 100 символов. В этом поле будет храниться ключ для сессий "запомнить меня", поддерживаемых вашим приложением. Это можно сделать с помощью %%$table->rememberToken();%% в миграции. == Хранение паролей == Класс %%Hash%% содержит методы для безопасного хэширования с помощью ((ВП:Bcrypt)). **Хэширование пароля по алгоритму Bcrypt** %% $password = Hash::make('secret'); %% **Проверка пароля по хэшу** %% if (Hash::check('secret', $hashedPassword)) { // Пароль подходит... } %% **Проверка на необходимость перехэширования пароля** %% if (Hash::needsRehash($hashed)) { $hashed = Hash::make('secret'); } %% == Авторизация пользователей == Для авторизации пользователя в вашем приложении используется метод %%Auth::attempt()%%: %% if (Auth::attempt(array('email' => $email, 'password' => $password))) { return Redirect::intended('dashboard'); } %% Заметьте, что поле **email** не обязательно и оно используется только для примера. Вы должны использовать любое поле, которое соответствует имени пользователя в вашей БД. Метод %%Redirect::intended()%% отправит пользователя на URL, который он пытался просмотреть до того, как запрос был перехвачен ((docs/v4/routing#фильтры_маршрутов фильтром)) авторизации. Дополнительный URL может быть передан в метод, если требуемый адрес не доступен. Когда вызывается метод %%Auth::attempt()%% возбуждается ((docs/v4/events событие)) %%(t)auth.attempt%%. При успешной авторизации также произойдёт событие %%(t)auth.login%%. **Проверка авторизации пользователя** Для определения того, авторизован ли пользователь или нет, можно использовать метод %%Auth::check()%%: %% if (Auth::check()) { // Пользователь уже вошёл в систему... } %% **Авторизация и запоминание пользователя** Если вы хотите предоставить функциональность типа "запомнить меня", то вы можете передать %%true%% вторым параметром к методу %%Auth::attempt()%%, который будет поддерживать авторизацию пользователя без ограничения по времени (пока он вручную не выйдет из системы). Разумеется, ваша таблица %%(t)users%% должна содержать строковое поле %%(t)remember_token%% для хранения ключа сессий "запомнить меня". %% if (Auth::attempt(array('email' => $email, 'password' => $password), true)) { // Пользователь был запомнен... } %% **Внимание:** если метод %%Auth::attempt()%% вернул %%true%%, то пользователь успешно вошёл в систему. %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) **Авторизован ли пользователь через запоминание?** Если вы "запоминаете" входы пользователей, то можете использовать метод %%viaRemember()%% для определения того, был ли пользователь авторизован с использованием cookie "запомнить меня": ~%% if (Auth::viaRemember()) { // } ~%% %% **Авторизация пользователя с условиями** Вы также можете передать дополнительные условия для запроса к таблице: %% if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1))) { // Вход, если пользователь активен, не отключен и существует. } %% .(alert) Для дополнительной защиты от фиксации сессии, ID сессии пользователя будет автоматически сгенерирован заново после авторизации. **Доступ к авторизованному пользователю** Как только пользователь авторизован вы можете обращаться к модели %%User%% и её свойствам: %% $email = Auth::user()->email; %% %%(DOCNEW 4.2=d7b13440c003218ed79e9d508706eca01990122f 4.12.2014 5:01:15) Для получения ID авторизованного пользователя используйте метод %%id()%%: ~%% $id = Auth::id(); ~%% %% Для простой авторизации пользователя по ID используется метод %%loginUsingId()%%: %% Auth::loginUsingId(1); %% **Проверка данных для входа без авторизации** Метод %%validate()%% позволяет вам проверить данные для входа без осуществления самого входа: %% if (Auth::validate($credentials)) { // } %% **Авторизация пользователя на один запрос** Вы также можете использовать метод %%once()%% для авторизации пользователя в системе только для одного запроса. ((docs/v4/session Сессии)) и ((docs/v4/requests#cookies)) не будут использованы. %% if (Auth::once($credentials)) { // } %% **Выход пользователя из системы** %% Auth::logout(); %% == Ручная авторизация == Если вам нужно авторизовать существующего пользователя просто передайте его модель в метод %%Auth::login()%%: %% $user = User::find(1); Auth::login($user); %% Это эквивалентно авторизации пользователя через его данные методом %%Auth::attempt()%%. == Защита маршрутов == Вы можете использовать ((docs/v4/routing#Фильтры)) ((docs/v4/routing маршрутов)), чтобы позволить только авторизованным пользователям обращаться к данному маршруту. Изначально Laravel содержит фильтр %%(t)auth%%, который содержится в файле %%(t)app/filters.php%%. **Защита маршрута** %% Route::get('profile', array('before' => 'auth', function () { // Доступно только авторизованным пользователям... })); %% == ((#csrf)) Защита от подделки запросов (CSRF) == Laravel предоставляет простой способ защиты вашего приложения от подделки межсайтовых запросов ([[ВП:CSRF]]). **Вставка CSRF-ключа в форму** %%(h) %% **Проверка переданного CSRF-ключа** %% Route::post('register', array('before' => 'csrf', function() { return 'Вы передали верный ключ!'; })); %% == Простая HTTP-авторизация == //HTTP Basic Authentication// - простой и быстрый способ авторизовать пользователей вашего приложения без создания дополнительной страницы входа. Для начала подключите фильтр %%(t)auth.basic%%. **Защита маршрута фильтром HTTP-авторизации** %% Route::get('profile', array('before' => 'auth.basic', function () { // Доступно только авторизованным пользователям... })); %% По умолчанию, фильтр %%(t)basic%% будет использовать поле %%$email%% модели объекта при авторизации. Если вы хотите использовать иное поле, можно передать его имя первым параметром методу %%basic()%% в вашем файле %%(t)app/filters.php%%: %% Route::filter('auth.basic', function() { return Auth::basic('username'); }); %% **Авторизация без запоминания состояния** Вы можете использовать HTTP-авторизацию без установки ((docs/v4/requests#cookie+s)) в ((docs/v4/session сессии)), что особенно удобно для авторизации в API. Для того, чтобы сделать это, зарегистрируйте фильтр, возвращающий результат вызова %%Auth::onceBasic()%%: %% Route::filter('basic.once', function () { return Auth::onceBasic(); }); %% Если вы используете PHP FastCGI, то по умолчанию простая HTTP-аутентификация не будет работать правильно. В файл %%(t).htaccess%% надо добавить следующие строки: %% RewriteCond %{HTTP:Authorization} ^(.+)$ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] %% == Сброс и изменение паролей == === Модель и таблица == Большая часть приложений позволяют пользователям сбрасывать свои забытые пароли. Вместо того, чтобы заставлять вас реализовывать эту функциональность в каждом приложении, Laravel предоставляет удобный способ для отправки писем о сбросе пароля и выполнения самого сброса. Для начала убедитесь, что модель %%User%% реализует интерфейс %%Illuminate\Auth\Reminders\RemindableInterface%%. Это уже сделано для модели %%User%%, включённой в фреймворк по умолчанию. .(tl_note) В Laravel 4.2 эта модель использует %%Illuminate\Auth\Reminders\RemindableTrait%% для включения методов, необходимых для реализации интерфейса. - //прим. пер.// **Реализация интерфейса %%RemindableInterface%%** %%(DOCNEW 4.2=d7b13440c003218ed79e9d508706eca01990122f 4.12.2014 5:01:15) ~%% use Illuminate\Auth\Reminders\RemindableTrait; use Illuminate\Auth\Reminders\RemindableInterface; class User extends Eloquent implements RemindableInterface { use RemindableTrait; } ~%% %% %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) ~%% class User extends Eloquent implements RemindableInterface { public function getReminderEmail() { return $this->email; } } ~%% %% **Генерация миграции для таблиц сброса паролей** Затем вам нужно создать таблицу для хранения ключей сброса паролей. Для создания миграции для таблицы просто выполните команду %%(t)auth:reminders-table%% интерфейса ((docs/v4/artisan Artisan)). %%(sh) php artisan auth:reminders-table php artisan migrate %% %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) === Контроллер сброса паролей == Теперь мы готовы к созданию контроллера сброса паролей. Чтобы автоматически создать контроллер, вы можете использовать Artisan-команду %%(sh)auth:reminders-controller%%, которая создаст файл %%(t)RemindersController.php%% в вашем каталоге %%(t)app/controllers%%. %%(sh) php artisan auth:reminders-controller ~%% В созданном контроллере уже будет метод %%getRemind()%%, который обрабатывает отображение вашей формы сброса пароля. Вам надо только создать ((/docs/v4/responses#шаблоны шаблон)) %%(t)password.remind%%. В этом шаблоне должна быть основная форма с полем %%(t)email%%. Форма должна отправлять POST-запрос в действие %%(t)RemindersController@postRemind%%. Простая форма в шаблоне %%(t)password.remind%% может выглядеть так: ~%%
~%% В дополнение к %%getRemind()%% в созданном контроллере будет метод %%postRemind()%%, который обрабатывает отправку оповещений о сбросе пароля вашим пользователям по электронной почте. Этот метод предполагает наличие поля %%(t)email%% в переменных %%(t)POST%%. Если оповещение будет успешно отправлено пользователю по электронной почте, то в сессию будет передано сообщение %%(t)status%%. Если оповещение не пройдёт, в сессию будет передано сообщение %%(t)error%%. В методе контроллера %%postRemind()%% вы можете изменить экземпляр сообщения перед его отправкой пользователю: ~%% Password::remind(Input::only('email'), function($message) { $message->subject('Password Reminder'); }); ~%% Ваш пользователь получит по электронной почте ссылку, которая указывает на метод контроллера %%getReset()%%. Ключ сброса пароля, который используется для идентификации данной попытки сброса пароля, также будет передан методу контроллера. Действие уже настроено, чтобы вернуть шаблон %%(t)password.reset%%, который вы должны создать. Ключ %%(t)token%% будет передан в шаблон, и вы должны поместить этот ключ в скрытое поле формы %%(t)token%%. Кроме поля %%(t)token%% форма сброса пароля должна содержать поля %%(t)email%%, %%(t)password%% и %%(t)password_confirmation%%. Форма должна отправлять POST-запрос в метод %%RemindersController@postReset%%. Простая форма в шаблоне %%(t)password.reset%% может выглядеть так: ~%% ~%% Наконец, метод %%postReset()%% отвечает за фактическое изменение пароля в хранилище. В этом действии контроллера замыкание, переданное в метод %%Password::reset()%%, устанавливает атрибут %%(t)password%% для %%(t)user%% и вызывает метод %%save%%. Конечно, это замыкание предполагает, что ваша модель %%(t)user%% является ((/docs/v4/eloquent моделью Eloquent)). Однако вы можете изменить это замыкание по мере необходимости, чтобы оно было совместимым с системой хранения базы данных вашего приложения. Если пароль успешно сброшен, пользователь будет перенаправлен в корень вашего приложения. Опять же, вы можете изменить URL этого перенаправления. Если сброс пароля не пройдёт, пользователь будет перенаправлен обратно в форму сброса, и в сессию будет передано сообщение %%(t)error%%. === Проверка пароля == По умолчанию метод %%Password::reset()%% будет проверять, что пароли совпадают и содержат не менее шести символов. Вы можете настроить эти правила, используя метод %%Password::validator()%%, который принимает замыкание. В этом замыкании, вы можете делать любые проверки пароля. Обратите внимание, что вам не надо проверять совпадение паролей, фреймворк сделает это автоматически. ~%% Password::validator(function($credentials) { return strlen($credentials['password']) >= 6; }); ~%% .(alert) По умолчанию ключи сброса пароля истекают через один час. Вы можете изменить это с помощью параметра %%(t)reminder.expire%% в вашем файле %%(t)app/config/auth.php%%. %% %%(DOCNEW 4.0=0da300f6445bec5a70d007f503834fce957b065b 16.10.2014 5:19:26) .(tl_note) Раздел применим только к версии Laravel 4.0. **Отправка уведомления о сбросе пароля** Для отправки уведомления вы можете использовать метод %%Password::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); }); ~%% Заметьте, что параметры, переданные в метод %%Password::remind()%%, похожи на те, которые передаются методу %%Auth::attempt()%%. Этот метод получит модель %%User%% и отправит соответствующее письмо со ссылкой для сброса. В ((docs/v4/templates шаблон)) письма будет передана переменная %%$token%%, которая может быть использована для изменения пароля через форму его сброса. Кроме неё будет также передана переменная %%$user%%. .(alert) **Внимание:** вы можете указать, какой шаблон должен использоваться при создании сообщения, изменив ((docs/v4/configuration настройку приложения)) %%(t)auth.reminder.email%%. Изначально фреймворк уже содержит нужный шаблон. Вы можете изменить объект письма, которое отправляется пользователю, передав замыкание в виде второго аргумента методу %%Password::remind()%%: ~%% return Password::remind($credentials, function ($message, $user) { $message->subject('Ваше уведомление о сбросе.'); }); ~%% Как вы можете заметить, в маршруте мы напрямую возвращаем результат вызова метода %%Password::remind()%%. По умолчанию этот метод возвращает переадресацию на текущий адрес, если возникла ошибка при сбросе пароля, при этом устанавливается ((docs/v4/session#одноразов+ые))ая переменная %%(t)error%%, а также %%(t)reason%%, которая используется для извлечения языковой строки из языкового файла %%(t)reminders%%. Если пароль был успешно сброшен, то будет установлена одноразовая переменная %%(t)success%%. Таким образом, ((docs/v4/templates шаблон)) для формы сброса пароля должен выглядеть примерно так: ~%% @if (Session::has('error')) {{ trans(Session::get('reason')) }} @elseif (Session::has('success')) На ваш e-mail было отправлено письмо с инструкциями о сбросе пароля. @endif ~%% === Сброс пароля (4.0) == Как только пользователь перешёл по ссылке в письме, он будет перенаправлен на форму со скрытым ключом %%(t)token%%, а также полями %%(t)password%% и %%(t)password_confirmation%%. Ниже - пример ((docs/v4/routing маршрута)) для формы сброса: ~%% Route::get('password/reset/{token}', function ($token) { return View::make('auth.reset')->with('token', $token); }); ~%% А сама форма может выглядеть так: ~%% @if (Session::has('error')) {{ trans(Session::get('reason')) }} @endif ~%% Обратите внимание, что мы снова используем ((docs/v4/session сессии)) для отображения ошибки, которая могла произойти при сбросе пароля. Дальше мы определяем 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'); }); }); ~%% При успешном сбросе объект %%User%% и пароль будут переданы в замыкание, что позволит вам сохранить изменённую модель. После этого вы можете вернуть объект %%Redirect%% или любой другой тип ответа, что и будет возвращено методом %%Password::reset()%%. Заметьте, что этот метод автоматически проверяет переданный ключ (%%(t)token%%), данные для входа и совпадение введённых паролей. По умолчанию время действия ключа для сброса пароля - час. Вы можете настроить это время с помощью параметра %%(t)reminder.expire%% в вашем файле %%(t)app/config/auth.php%%. Также, по аналогии с методом %%Password::remind()%%, если во время сброса произошла ошибка метод %%Password::reset()%% вернёт объект %%Redirect%% на текущий адрес с ((docs/v4/session#одноразов+ые))ыми переменными %%(t)error%% и %%(t)reason%%. %% == Шифрование == Laravel предоставляет функции для устойчивого шифрования по алгоритму ((ВП:AES)) с помощью расширения ((phpdoc:book.mcrypt mcrypt)) для PHP. **Шифрование строки** %% $encrypted = Crypt::encrypt('секрет'); %% .(tl_note) **Внимание:** версия 4.2 перешла на 128-битный AES, а 4.1 и ниже использовала 256-битный. Это значит, что преждезакодированные значения после обновления раскодировать не получится - см. ((/docs/v4/upgrade руководство по обновлению)) - //прим. пер.// .(alert) **Внимание:** обязательно установите 16, 24 или 32-значный ключ **key** (!!(tl_note) до версии 4.2 - только 32-значный - //прим. пер.//!!) в файле %%(t)app/config/app.php%%. Если этого не сделать, зашифрованные строки не будут безопасными. **Расшифровка строки** %% $decrypted = Crypt::decrypt($encryptedValue); %% **Изменение алгоритма и режима шифрования** %% Crypt::setMode('ctr'); Crypt::setCipher($cipher); %% %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) == Драйверы авторизации == Laravel предоставляет драйверы авторизации %%(t)database%% и %%(t)eloquent%% прямо из коробки. Для получения дополнительной информации о добавлении дополнительных драйверов авторизации прочитайте ((/docs/v4/extending#авторизация документации по расширению авторизации)). %%