Введение
Хотите сразу попробовать? Просто выполните команды shphp artisan make:auth
и shphp artisan migrate
в свежем приложении Laravel. Затем откройте в браузере http://your-app.dev/register или любой другой URL, назначенный вашему приложению. Эти команды создадут заготовку для всей вашей системы аутентификации!
В Laravel сделать аутентификацию очень просто. Фактически, почти всё сконфигурировано для вас уже из коробки. Конфигурационный файл аутентификации расположен в config/auth.php. Он содержит несколько хорошо описанных опций для тонкой настройки поведения служб аутентификации.
Средства Laravel для аутентификации состоят из «защитников» и «провайдеров». Защитники определяют то, как аутентифицируются пользователи для каждого запроса. Например, Laravel поставляется с защитником «session», который поддерживает состояние с помощью хранилища сессий и cookies.
Провайдеры определяют то, как пользователи извлекаются из вашего постоянного хранилища. Laravel поставляется с поддержкой извлечения пользователей с помощью Eloquent и конструктора запросов БД. Но при необходимости вы можете определить для своего приложения дополнительные провайдеры.
Не переживайте, если сейчас это звучит запутанно! Для многих приложений никогда не потребуется изменять стандартные настройки аутентификации.
Требования для базы данных
По умолчанию в Laravel есть модель Eloquent App\User в вашем каталоге app. Эта модель может использоваться с базовым драйвером аутентификации Eloquent. Если ваше приложение не использует Eloquent, вы можете использовать драйвер аутентификации database, который использует конструктор запросов Laravel.
При создании схемы базы данных для модели App\User создайте столбец для паролей с длиной не менее 60 символов. Хорошим выбором для строкового столбца будет длина 255 символов.
Кроме того, перед началом работы удостоверьтесь, что ваша таблица users (или эквивалентная) содержит строковый столбец remember_token на 100 символов с допустимым значением NULL. Этот столбец будет использоваться, чтобы хранить ключи для пользователей, выбравших параметр «запомнить меня» при входе в приложение.
Краткое руководство по аутентификации
Laravel поставляется с несколькими контроллерами аутентификации, расположенными в пространстве имён App\Http\Controllers\Auth.
добавлено в 5.3 ()
Каждый из этих контроллеров использует типажи для подключения необходимых методов. Для многих приложений вам вообще не придётся изменять эти контроллеры.
Маршрутизация
Laravel обеспечивает быстрый способ создания заготовок всех необходимых для аутентификации маршрутов и представлений с помощью одной команды:
shphp artisan make:auth
Эту команду надо использовать на свежем приложении, она установит представление макета, представления для регистрации и входа, а также маршруты для всех конечных точек аутентификации. Также будет сгенерирован HomeController для обслуживания запросов к панели настроек вашего приложения после входа.
По умолчанию в Laravel нет маршрутов для запросов к контроллерам аутентификации. Вы можете добавить их вручную в файле app/Http/routes.php:
// Маршруты аутентификации...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
// Маршруты регистрации...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');
Представления
Как было сказано в предыдущем разделе, команда shphp artisan make:auth
создаст все необходимые вам представления для аутентификации и поместит их в папку resources/views/auth` directory.
Также команда shmake:auth
создаст папку resources/views/layouts, содержащую основной макет для вашего приложения. Все эти представления используют CSS-фреймворк Bootstrap, но вы можете изменять их как угодно.
Не смотря на то, что контроллеры аутентификации включены в фреймворк, вам необходимо предоставить представления, которые эти контроллеры смогут отрисовать. Представления необходимо расположить в каталоге resources/views/auth. Вы вольны настроить эти представления так, как сами желаете. Представление для входа в систему должно быть в resources/views/auth/login.blade.php, а представление для регистрации — в resources/views/auth/register.blade.php.
<!-- resources/views/auth/login.blade.php -->
<form method="POST" action="/auth/login">
{!! csrf_field() !!}
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
Password
<input type="password" name="password" id="password">
</div>
<div>
<input type="checkbox" name="remember"> Remember Me
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
<!-- resources/views/auth/register.blade.php -->
<form method="POST" action="/auth/register">
{!! csrf_field() !!}
<div>
Name
<input type="text" name="name" value="{{ old('name') }}">
</div>
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
Password
<input type="password" name="password">
</div>
<div>
Confirm Password
<input type="password" name="password_confirmation">
</div>
<div>
<button type="submit">Register</button>
</div>
</form>
Аутентификация
Теперь, когда у вас есть маршруты и представления для имеющихся контроллеров аутентификации, вы готовы регистрировать и аутентифицировать новых пользователей своего приложения. Вы можете просто перейти по этим маршрутам в браузере, поскольку контроллеры аутентификации уже содержат логику (благодаря их типажам) для аутентификации существующих пользователей и сохранения новых пользователей в базе данных.
добавлено в 5.3 ()
Когда пользователь успешно аутентифицируется, он будет перенаправлен на URI /home (для версии 5.2 — URI /). Вы можете изменить место для перенаправления после входа, задав свойство redirectTo контроллеров LoginController, RegisterController и ResetPasswordController (для версии 5.2 — контроллера AuthController):
protected $redirectTo = '/';
добавлено в 5.2 ()
добавлено в 5.3 ()
Если для генерирования пути для переадресации необходима дополнительная логика, вы можете определить метод PHPredirectTo()
вместо свойства redirectTo:
protected function redirectTo()
{
//
}
У метода PHPredirectTo()
приоритет выше, чем у атрибута redirectTo.
По умолчанию Laravel использует для аутентификации поле email. Чтобы изменить это, определите метод PHPusername()
в своём LoginController:
public function username()
{
return 'username';
}
добавлено в 5.2 ()
Когда аутентификация пользователя не успешна, он автоматически будет перенаправлен обратно на форму входа.
Чтобы изменить место для перенаправления после выхода из приложения, вы можете задать свойство redirectAfterLogout контроллера AuthController:
protected $redirectAfterLogout = '/login';
Если это свойство не задано, пользователь будет перенаправлен на URI /.
добавлено в 5.3 ()
Вы также можете изменить «защитника», используемого для аутентификации и регистрации пользователей. Для начала определите метод PHPguard()
в контроллерах LoginController, RegisterController и ResetPasswordController. Метод должен возвращать экземпляр защитника:
use Illuminate\Support\Facades\Auth;
protected function guard()
{
return Auth::guard('guard-name');
}
добавлено в 5.2 ()
Когда пользователь успешно аутентифицирован, он будет переадресован к URI /home, для обработки которой вам необходимо будет зарегистрировать маршрут. Вы можете настроить место для переадресации после аутентификации, задав свойство redirectPath в AuthController:
protected $redirectPath = '/dashboard';
Когда аутентификация пользователя не успешна, он будет переадресован на URI /auth/login. Вы можете настроить место для переадресации после неудачной аутентификации, задав свойство loginPath в AuthController:
protected $loginPath = '/login';
Свойство loginPath не влияет на то, куда будут переходить пользователи при попытке доступа к защищённому маршруту. Это контролируется методом PHPhandle()
посредника App\Http\Middleware\Authenticate.
Настройка хранилища/проверки ввода
Чтобы изменить требуемые поля для формы регистрации нового пользователя, или для изменения способа добавления новых пользователей в вашу базу данных, вы можете изменить класс RegisterController (для версии 5.2 — AuthController). Этот класс отвечает за проверку ввода и создание новых пользователей в вашем приложении.
Метод PHPvalidator()
класса RegisterController (для версии 5.2 — AuthController) содержит правила проверки ввода данных для новых пользователей приложения, а метод PHPcreate()
этого класса отвечает за создание новых записей App\User в вашей базе данных с помощью Eloquent ORM. Вы можете изменить каждый из этих методов, как пожелаете.
Получение аутентифицированного пользователя
Вы можете обращаться к аутентифицированному пользователю через фасад Auth:
use Illuminate\Support\Facades\Auth;
// Получить текущего аутентифицированного пользователя...
$user = Auth::user();
// Получить ID текущего аутентифицированного пользователя...
$id = Auth::id();
Или, когда пользователь аутентифицирован, вы можете обращаться к нему через экземпляр Illuminate\Http\Request. Не забывайте, указание типов классов приводит к их автоматическому внедрению в методы вашего контроллера:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
//для версии 5.1 и ранее:
//use Illuminate\Routing\Controller;
class ProfileController extends Controller
{
/**
* Обновление профиля пользователя.
*
* @param Request $request
* @return Response
*/
public function update(Request $request)
{
// $request->user() возвращает экземпляр аутентифицированного пользователя...
}
}
добавлено в 5.0 ()
Также вы можете указать тип контракта Illuminate\Contracts\Auth\Authenticatable. Это указание типа может быть добавлено к конструктору контроллера, методу контроллера или любому другому конструктору класса, реализуемому в сервис-контейнере:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Contracts\Auth\Authenticatable;
class ProfileController extends Controller {
/**
* Обновление профиля пользователя.
*
* @return Response
*/
public function updateProfile(Authenticatable $user)
{
// $user - это экземпляр аутентифицированного пользователя...
}
}
Определение, аутентифицирован ли пользователь
Чтобы определить, что пользователь уже вошёл в ваше приложение, вы можете использовать метод PHPcheck()
фасада Auth, который вернёт true, если пользователь аутентифицирован:
use Illuminate\Support\Facades\Auth;
if (Auth::check())
{
// Пользователь вошёл в систему...
}
Можно определить, аутентифицирован ли пользователь, методом PHPcheck()
, но обычно вы будете использовать посредника, чтобы проверить, аутентифицирован ли пользователь, до предоставления ему доступа к определённым маршрутам/контроллерам, вы можете использовать посредника. Подробнее об этом читайте в разделе Защита маршрутов.
Защита маршрутов
Посредник Route можно использовать, чтобы давать доступ к определённому маршруту только аутентифицированным пользователям.
добавлено в 5.3 ()
Laravel поставляется с посредником auth, который определён в Illuminate\Auth\Middleware\Authenticate. Поскольку посредник уже зарегистрирован в вашем HTTP-ядре, вам остаётся только присоединить его к определению маршрута:
Route::get('profile', function () {
// Только аутентифицированные пользователи могут зайти...
})->middleware('auth');
добавлено в 5.2 () 5.1 () 5.0 ()
Laravel поставляется с посредником auth, который определён в app\Http\Middleware\Authenticate.php. Всё, что вам надо сделать — это присоединить его к определению маршрута:
// С помощью замыкания маршрута...
Route::get('profile', ['middleware' => 'auth', function() {
// Только аутентифицированные пользователи могут зайти...
}]);
// С помощью контроллера...
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'ProfileController@show'
]);
Конечно, если вы используете контроллеры, вы можете вызвать метод PHPmiddleware()
из конструктора контроллера, вместо присоединения его напрямую к определению маршрута:
public function __construct()
{
$this->middleware('auth');
}
добавлено в 5.3 ()
Во время прикрепления посредника auth к маршруту, вы можете также указать, какой защитник должен быть использован для аутентификации пользователя. Указанный защитник должен соответствовать одному из ключей в массиве guards вашего файла auth.php:
public function __construct()
{
$this->middleware('auth:api');
}
добавлено в 5.2 ()
Во время прикрепления посредника auth к маршруту, вы можете также указать, какой защитник должен быть использован для выполнения аутентификации:
Route::get('profile', [
'middleware' => 'auth:api',
'uses' => 'ProfileController@show'
]);
Указанный защитник должен соответствовать одному из ключей в массиве guards конфигурационного файла PHPauth.php
.
добавлено в 5.3 ()
Блокировка входа
Если вы используете встроенный в Laravel класс LoginController, то типаж Illuminate\Foundation\Auth\ThrottlesLogins уже включён в ваш контроллер. По умолчанию пользователь не сможет войти в приложение в течение одной минуты, если он несколько раз указал неправильные данные для входа. Блокировка происходит отдельно для имени пользователя/адреса e-mail и его IP-адреса.
Блокировка аутентификации
Если вы используете встроенный в Laravel класс AuthController, то вы можете использовать типаж Illuminate\Foundation\Auth\ThrottlesLogins для блокировки попыток входа в ваше приложение. По умолчанию пользователь не сможет войти в приложение в течение одной минуты, если он несколько раз указал неправильные данные для входа. Блокировка происходит отдельно для имени пользователя/адреса e-mail и его IP-адреса:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
// Остальное содержимое класса...
}
Ручная аутентификация
Если вы не хотите использовать встроенные контроллеры аутентификации, вам нужно будет напрямую управлять аутентификацией пользователей, используя классы аутентификации Laravel. Не волнуйтесь, они не кусаются!
Мы будем работать со службами аутентификации Laravel через фасад Auth, поэтому нам надо не забыть импортировать фасад Auth в начале класса. Далее давайте посмотрим на метод PHPattempt()
:
<?php namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
//для версии 5.2:
//use Auth;
//для версии 5.1 и ранее:
//use Illuminate\Routing\Controller;
class LoginController extends Controller
//для версии 5.2 и ранее:
//class AuthController extends Controller
{
/**
* Обработка попытки аутентификации
*
* @return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Аутентификация успешна
return redirect()->intended('dashboard');
}
}
}
Метод PHPattempt()
принимает массив пар ключ/значение в качестве первого аргумента. Значения массива будут использованы для поиска пользователя в таблице базы данных. Так, в приведённом выше примере пользователь будет получен по значению столбца email. Если пользователь будет найден, хешированный пароль, сохранённый в базе данных, будет сравниваться с хешированным значением password, переданным в метод через массив. Если два хешированных пароля совпадут, то для пользователя будет запущена новая аутентифицированная сессия.
Метод PHPattempt()
вернёт true, если аутентификация прошла успешно. В противном случае будет возвращён false.
Метод PHPintended()
«переадресатора» перенаправит пользователя к тому URL, к которому он обращался до того, как был перехвачен посредником аутентификации. В этот метод можно передать запасной URI, на случай недоступности требуемого пути.
Указание дополнительных условий
При необходимости вы можете добавить дополнительные условия к запросу аутентификации, помимо адреса e-mail и пароля. Например, можно проверить отметку «активности» пользователя:
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Пользователь активен, не приостановлен, и существует.
}
В этих примерах email не является обязательным вариантом, он приведён только для примера. Вы можете использовать какой угодно столбец, соответствующий «username» в вашей базе данных.
Обращение к конкретным экземплярам защитника
С помощью метода PHPguard()
фасада Auth вы можете указать, какой экземпляр защитника необходимо использовать. Это позволяет управлять аутентификацией для отдельных частей вашего приложения, используя полностью отдельные модели для аутентификации или таблицы пользователей.
Передаваемое в метод PHPguard()
имя защитника должно соответствовать одному из защитников, настроенных в файле auth.php:
if (Auth::guard('admin')->attempt($credentials)) {
//
}
Для завершения сессии пользователя можно использовать метод PHPlogout()
фасада Auth. Он очистит информацию об аутентификации в сессии пользователя:
Auth::logout();
Запоминание пользователей
Если вы хотите обеспечить функциональность «запомнить меня» в вашем приложении, вы можете передать логическое значение как второй параметр методу PHPattempt()
, который сохранит пользователя аутентифицированным на неопределённое время, или пока он вручную не выйдет из системы. Конечно, ваша таблица users должна содержать строковый столбец remember_token, который будет использоваться для хранения ключей «запомнить меня».
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// Пользователь запомнен...
}
добавлено в 5.3 ()
Если вы «запоминаете» пользователей, вы можете использовать метод PHPviaRemember()
, чтобы определить, аутентифицировался ли пользователь, используя cookie «запомнить меня»:
if (Auth::viaRemember()) {
//
}
Другие методы аутентификации
Аутентификация экземпляра пользователя
Если вам необходимо «залогинить» в приложение существующий экземпляр пользователя, вызовите метод PHPcall()
с экземпляром пользователя. Данный объект должен быть реализацией контракта Illuminate\Contracts\Auth\Authenticatable. Само собой, встроенная в Laravel модель App\User реализует этот интерфейс:
Auth::login($user);
добавлено в 5.2 ()
Аутентификация пользователя по ID
Для входа пользователя в приложение по его ID, используйте метод PHPloginUsingId()
. Этот метод просто принимает первичный ключ пользователя, которого необходимо аутентифицировать:
Auth::loginUsingId(1);
добавлено в 5.2 ()
// Войти и "запомнить" данного пользователя...
Auth::loginUsingId(1, true);
добавлено в 5.0 ()
Вход пользователя для одного запроса
Вы также можете использовать метод PHPonce()
для пользовательского входа в систему для одного запроса. Сеансы и cookies не будут использоваться, что может быть полезно при создании API без состояний (stateless API):
if (Auth::once($credentials)) {
//
}
Простая HTTP-аутентификация
HTTP Basic Authentication — простой и быстрый способ аутентификации пользователей вашего приложения без создания дополнительной страницы входа. Для начала прикрепите посредника auth.basic к своему маршруту. Этот посредник встроен в Laravel, поэтому вам не надо определять его:
добавлено в 5.3 ()
Route::get('profile', function () {
// Только аутентифицированные пользователи могут зайти...
})->middleware('auth.basic');
добавлено в 5.2 () 5.1 () 5.0 ()
Route::get('profile', ['middleware' => 'auth.basic', function() {
// Только аутентифицированные пользователи могут зайти...
}]);
Когда посредник прикреплён к маршруту, вы автоматически получите запрос данных для входа при обращении к маршруту через браузер. По умолчанию посредник auth.basic будет использовать столбец email из записи пользователя в качестве «username».
Если вы используете PHP FastCGI, то простая HTTP-аутентификация изначально может работать неправильно. Надо добавить следующие строки к вашему файлу .htaccess:
confRewriteCond %{HTTP:Authorization} ^(.+)$ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Простая Stateless HTTP-аутентификация
Вы также можете использовать простую HTTP-аутентификацию, не задавая пользовательскую cookie для сессии, что особенно полезно для API-аутентификации. Чтобы это сделать, определите посредника, который вызывает метод PHPonceBasic()
. Если этот метод ничего не возвращает, запрос может быть передан дальше в приложение:
<?php
namespace Illuminate\Auth\Middleware;
use Illuminate\Support\Facades\Auth;
//для версии 5.2 и ранее:
//use Auth;
//use Closure;
class AuthenticateOnceWithBasicAuth
{
/**
* Обработка входящего запроса.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, $next)
//для версии 5.2 и ранее:
//public function handle($request, Closure $next)
{
return Auth::onceBasic() ?: $next($request);
}
}
Затем зарегистрируйте посредника маршрута и прикрепите его к маршруту:
добавлено в 5.3 ()
Route::get('api/user', function () {
// Только аутентифицированные пользователи могут зайти...
})->middleware('auth.basic.once');
добавлено в 5.2 () 5.1 () 5.0 ()
Route::get('api/user', ['middleware' => 'auth.basic.once', function() {
// Только аутентифицированные пользователи могут зайти...
}]);
Сброс и изменение паролей
В документации по ветке 5.3 и далее данный раздел статьи был вынесен в отдельную статью — Сброс пароля — прим. пер.
Требования для базы данных
Большинство веб-приложений предоставляет пользователям возможность сбросить их забытые пароли. Вместо того, чтобы постоянно реализовывать это в каждом новом приложении, Laravel предлагает удобные методы для отправки писем о сбросе пароля и выполнении самого сброса.
Для начала проверьте, что ваша модель App\User реализует контракт Illuminate\Contracts\Auth\CanResetPassword. Конечно, модель App\User, встроенная во фреймворк, уже реализует этот интерфейс и использует типаж Illuminate\Auth\Passwords\CanResetPassword для подключения методов, необходимых для реализации интерфейса.
Создание миграции для таблицы сброса паролей
Затем должна быть создана таблица для хранения ключей сброса пароля. Миграция для этой таблицы включена в Laravel, и находится в каталоге database/migrations. Вам остаётся только выполнить миграцию:
shphp artisan migrate
Маршрутизация
Laravel содержит Auth\PasswordController, который содержит логику, необходимую для сброса пользовательских паролей.
добавлено в 5.2 ()
Но вам надо определить маршруты для запросов к этому контроллеру:
// Маршруты запроса ссылки для сброса пароля...
Route::get('password/email', 'Auth\PasswordController@getEmail');
Route::post('password/email', 'Auth\PasswordController@postEmail');
// Маршруты сброса пароля...
Route::get('password/reset/{token}', 'Auth\PasswordController@getReset');
Route::post('password/reset', 'Auth\PasswordController@postReset');
Представления
добавлено в 5.2 ()
Кроме определения маршрутов для PasswordController, вам надо предоставить представления, которые могут быть возвращены этим контроллером. Не волнуйтесь, мы предоставили примеры представлений, чтобы вам было легче начать. Вы можете изменить эти шаблоны под дизайн своего приложения.
Пример формы запроса ссылки для сброса пароля
Вам надо сделать HTML-представление для формы запроса сброса пароля. Это представление должно быть помещено в resources/views/auth/password.blade.php. Эта форма предоставляет единственное поле для ввода адреса e-mail, позволяя запросить ссылку для сброса пароля:
<!-- resources/views/auth/password.blade.php -->
<form method="POST" action="/password/email">
{!! csrf_field() !!}
@if (count($errors) > 0)
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
<button type="submit">
Send Password Reset Link
</button>
</div>
</form>
Когда пользователь подтвердит запрос на сброс пароля, он получит электронное письмо со ссылкой, которая указывает на метод PHPgetReset()
(обычно расположенный по маршруту /password/reset) контроллера PasswordController. Вам надо создать представление для этого письма в resources/views/emails/password.blade.php. Представление получит переменную PHP$token
, которая содержит ключ для сброса пароля, по которому происходит сопоставление пользователя с запросом сброса пароля. Вот пример представления для e-mail:
<!-- resources/views/emails/password.blade.php -->
Нажмите здесь для сброса пароля: {{ url('password/reset/'.$token) }}
Когда пользователь переходит по ссылке из письма для сброса пароля, ему автоматически будет выведена форма сброса пароля. Это представление необходимо поместить в resources/views/auth/reset.blade.php.
Вот пример формы сброса пароля:
<!-- resources/views/auth/reset.blade.php -->
<form method="POST" action="/password/reset">
{!! csrf_field() !!}
<input type="hidden" name="token" value="{{ $token }}">
@if (count($errors) > 0)
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
Password
<input type="password" name="password">
</div>
<div>
Confirm Password
<input type="password" name="password_confirmation">
</div>
<div>
<button type="submit">
Reset Password
</button>
</div>
</form>
После сброса пароля
Когда вы определили маршруты и представления для сброса паролей пользователей, вы можете просто обратиться к данному маршруту через браузер (/password/reset). Встроенный в фреймворк PasswordController содержит логику отправки сообщений со ссылкой для сброса пароля, а также логику обновления паролей в базе данных.
После сброса пароля пользователь автоматически войдёт в приложение и будет перенаправлен к /home. Вы можете изменить этот путь задав свойство redirectTo в PasswordController:
protected $redirectTo = '/dashboard';
По умолчанию ключи сброса пароля истекают через один час. Вы можете изменить это с помощью параметра expire в вашем файле config/auth.php.
Настройка
добавлено в 5.2 ()
Настройка защитника аутентификации
В файле настроек auth.php вы можете настроить несколько «защитников», которых можно использовать для задания логики аутентификации для нескольких таблиц пользователей. Вы можете изменить встроенный PasswordController, чтобы он использовал необходимого вам защитника, добавив в контроллер свойство $guard:
/**
* Будет использоваться указанный защитник аутентификации.
*
* @var string
*/
protected $guard = 'admins';
Вы можете настроить несколько «брокеров» паролей в файле настроек auth.php, их можно использовать для сброса паролей в нескольких таблицах пользователей. Вы можете изменить встроенный PasswordController, чтобы он использовал необходимого вам брокера, добавив в контроллер свойство $broker:
/**
* Будет использоваться указанный брокер паролей.
*
* @var string
*/
protected $broker = 'admins';
Добавление собственных защитников
Вы можете определить своих собственных защитников аутентификации с помощью метода PHPextend()
фасада Auth. Вам нужно разместить этот вызов «провайдера» в сервис-провайдере. Поскольку в Laravel уже есть AuthServiceProvider, мы можем поместить код в этот провайдер:
добавлено в 5.3 ()
<?php
namespace App\Providers;
use App\Services\Auth\JwtGuard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Регистрация всех сервисов аутентификации/авторизации приложения.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::extend('jwt', function ($app, $name, array $config) {
// Вернуть экземпляр Illuminate\Contracts\Auth\Guard...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
}
добавлено в 5.2 ()
<?php
namespace App\Providers;
use Auth;
use App\Services\Auth\JwtGuard;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Выполнение после-регистрационной загрузки сервисов.
*
* @return void
*/
public function boot()
{
Auth::extend('jwt', function($app, $name, array $config) {
// Вернуть экземпляр Illuminate\Contracts\Auth\Guard...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
/**
* Регистрация привязок в контейнере.
*
* @return void
*/
public function register()
{
//
}
}
Как видите, в этом примере переданная в метод PHPextend()
функция обратного вызова должна вернуть реализацию Illuminate\Contracts\Auth\Guard. Этот интерфейс содержит несколько методов, которые вам надо реализовать, для определения собственного защитника. Когда вы определили своего защитника, вы можете использовать его в настройке guards в вашем файле auth.php:
conf'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
Социальная аутентификация
Для версии 5.2 и выше данный раздел перенесён на GitHub — прим. пер.
В дополнение к обычной аутентификации на основе формы, Laravel также предоставляет простой и удобный способ аутентификации с помощью провайдеров OAuth, используя Laravel Socialite. Socialite в настоящее время поддерживает аутентификацию через Facebook, Twitter, LinkedIn, Google, GitHub и Bitbucket.
Чтобы начать работать с Socialite, добавьте зависимость в свой файл composer.json:
confcomposer require laravel/socialite
Настройка
После установки библиотеки Socialite зарегистрируйте Laravel\Socialite\SocialiteServiceProvider в своем конфигурационном файле config/app.php.
conf'providers' => [ // Другие сервис-провайдеры... Laravel\Socialite\SocialiteServiceProvider::class, ],
Также добавьте фасад Socialite в массив aliases в файле app:
conf'Socialite' => Laravel\Socialite\Facades\Socialite::class,
Вам будет необходимо добавить учётные данные для сервисов OAuth, которые использует ваше приложение. Эти учётные данные должны быть помещены в ваш конфигурационный файл config/services.php и должны использовать ключ facebook, twitter, linkedin, google, github или bitbucket, в зависимости от провайдеров, которые необходимы вашему приложению. Например:
conf'github' => [ 'client_id' => 'your-github-app-id', 'client_secret' => 'your-github-app-secret', 'redirect' => 'http://your-callback-url', ],
Основы использования
Теперь можно аутентифицировать пользователей! Вам будут нужны два маршрута: один для перенаправления пользователя на провайдер OAuth, и второй для получения обратного вызова от провайдера после аутентификации. Мы обратимся к Socialite через фасад Socialite:
<?php
namespace App\Http\Controllers;
use Socialite;
use Illuminate\Routing\Controller;
class AuthController extends Controller
{
/**
* Переадресация пользователя на страницу аутентификации GitHub.
*
* @return Response
*/
public function redirectToProvider()
{
return Socialite::driver('github')->redirect();
}
/**
* Получение информации о пользователе от GitHub.
*
* @return Response
*/
public function handleProviderCallback()
{
$user = Socialite::driver('github')->user();
// $user->token;
}
}
Метод PHPredirect()
отвечает за отправку пользователя провайдеру OAuth, а метод PHPuser()
читает входящий запрос и получает информацию пользователя от провайдера. Прежде чем перенаправить пользователя, вы можете также установить «области видимости» для запроса с помощью метода PHPscope()
. Этот метод переопределит все существующие области видимости:
return Socialite::driver('github')
->scopes(['scope1', 'scope2'])->redirect();
Само собой, вам необходимо определить маршруты для ваших методов контроллера:
Route::get('auth/github', 'Auth\AuthController@redirectToProvider');
Route::get('auth/github/callback', 'Auth\AuthController@handleProviderCallback');
Некоторые из провайдеров OAuth поддерживают необязательные параметры в запросе переадресации. Чтобы включить какие-либо необязательные параметры в запрос, вызовите метод PHPwith()
с ассоциативным массивом:
return Socialite::driver('google')
->with(['hd' => 'example.com'])->redirect();
Получение пользовательских данных
Когда у вас есть экземпляр пользователя, вы можете получить более подробную информацию о пользователе:
$user = Socialite::driver('github')->user();
// Два провайдера OAuth
$token = $user->token;
// Один провайдер OAuth
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// Все провайдеры
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
Добавление собственных провайдеров пользователей
Если вы не используете традиционную реляционную базу данных для хранения ваших пользователей, вам необходимо добавить в Laravel свой собственный провайдер аутентификации пользователей. Мы используем метод PHPprovider()
фасада Auth для определения своего драйвера:
добавлено в 5.3 ()
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Регистрация всех сервисов аутентификации/авторизации приложения.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('riak', function ($app, array $config) {
// Возврат экземпляра Illuminate\Contracts\Auth\UserProvider...
return new RiakUserProvider($app->make('riak.connection'));
});
}
}
добавлено в 5.2 ()
<?php
namespace App\Providers;
use Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Выполнение пост-регистрационной загрузки служб.
*
* @return void
*/
public function boot()
{
Auth::provider('riak', function($app, array $config) {
// Возврат экземпляра Illuminate\Contracts\Auth\UserProvider...
return new RiakUserProvider($app['riak.connection']);
});
}
/**
* Регистрация привязок в контейнере.
*
* @return void
*/
public function register()
{
//
}
}
После регистрации провайдера методом PHPprovider()
, вы можете переключиться на новый провайдер в файле настроек auth.php. Сначала определите «провайдера», который использует ваш новый драйвер:
conf'providers' => [ 'users' => [ 'driver' => 'riak', ], ],
И наконец, вы можете использовать этот провайдер в вашей настройке 'guards':
conf'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], ],
добавлено в 5.1 ()
Добавление драйверов аутентификации
Данный раздел статьи добавлен в документацию для версии 5.1.
Для версий 5.2 и выше и 5.0 и ниже он неактуален.
Если вы не используете традиционную реляционную базу данных для хранения ваших пользователей, вам необходимо добавить в Laravel свой собственный драйвер аутентификации. Мы используем метод PHPextend()
фасада Auth для определения своего драйвера. Вам надо поместить этот вызов метода PHPextend()
в сервис-провайдер:
<?php
namespace App\Providers;
use Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Выполнение пост-регистрационной загрузки служб.
*
* @return void
*/
public function boot()
{
Auth::extend('riak', function($app) {
// Возврат экземпляра Illuminate\Contracts\Auth\UserProvider...
return new RiakUserProvider($app['riak.connection']);
});
}
/**
* Регистрация привязок в контейнере.
*
* @return void
*/
public function register()
{
//
}
}
После регистрации драйвера методом PHPextend()
, вы можете переключиться на новый драйвер в файле настроек config/auth.php.
Контракт User Provider
Реализации Illuminate\Contracts\Auth\UserProvider отвечают только за извлечение реализаций Illuminate\Contracts\Auth\Authenticatable из постоянных систем хранения, таких как MySQL, Riak, и т.п. Эти два интерфейса позволяют механизмам аутентификации Laravel продолжать функционировать независимо от того, как хранятся данные пользователей и какой тип класса использован для их представления.
Давайте посмотрим на контракт Illuminate\Contracts\Auth\UserProvider:
<?php
namespace Illuminate\Contracts\Auth;
interface UserProvider {
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}
Функция PHPretrieveById()
обычно принимает ключ, отображающий пользователя, такой как автоинкрементный ID из базы данных MySQL. Реализация Authenticatable, соответствующая этому ID, должна быть получена и возвращена этим методом.
Функция PHPretrieveByToken()
принимает пользователя по его уникальному PHP$identifier
и ключу PHP$token
«запомнить меня», хранящемуся в поле remember_token. Как и предыдущий метод, он должен возвращать реализацию Authenticatable.
Метод PHPupdateRememberToken()
обновляет поле remember_token пользователя PHP$user
значением нового PHP$token
. Новый ключ может быть как свежим ключом, назначенным при успешной попытке входа «запомнить меня», так и PHPnull
при выходе пользователя.
Метод PHPretrieveByCredentials()
принимает массив авторизационных данных, переданных в метод PHPAuth::attempt()
при попытке входа в приложение. Затем метод должен «запросить» у основного постоянного хранилища того пользователя, который соответствует этим авторизационным данным. Обычно этот метод выполняет запрос с условием «where» для PHP$credentials['username']
. Затем метод должен вернуть реализацию Authenticatable (для версии 5.2 и ранее —
UserInterface). Этот метод не должен пытаться проверить пароль или аутентифицировать пользователя.
Метод PHPvalidateCredentials()
должен сравнить данного PHP$user
с PHP$credentials
для аутентификации пользователя. Например, этот метод может использовать PHPHash::check
для сравнения строки PHP$user->getAuthPassword()
со значением PHP$credentials['password']
. Этот метод должен возвращать PHPtrue
или PHPfalse
, сообщая о правильности пароля.
Контракт Authenticatable
Теперь, когда мы изучили каждый метод в UserProvider, давайте посмотрим на контракт Authenticatable. Помните, провайдер должен вернуть реализацию этого интерфейса из методов PHPretrieveById()
и PHPretrieveByCredentials()
:
<?php
namespace Illuminate\Contracts\Auth;
interface Authenticatable {
public function getAuthIdentifierName(); //для версии 5.2 и выше
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}
Этот интерфейс прост. Метод PHPgetAuthIdentifierName()
должен возвращать имя поля «первичного ключа» пользователя (для версии 5.2 и выше), а метод PHPgetAuthIdentifier()
должен возвращать «первичный ключ» пользователя. При использовании MySQL это будет автоинкрементный первичный ключ. Метод PHPgetAuthPassword ()
должен возвращать хешированный пароль пользователя. Этот интерфейс позволяет системе аутентификации работать с классом User, независимо от используемой ORM и уровня абстракции хранилища. По умолчанию Laravel содержит в папке app класс User, который реализует этот интерфейс. Вы можете подсмотреть в нём пример реализации.
События
Laravel генерирует различные события в процессе аутентификации. Вы можете прикрепить слушателей к этим событиям в вашем EventServiceProvider:
добавлено в 5.3 ()
/**
* Сопоставления слушателя событий для вашего приложения.
*
* @var array
*/
protected $listen = [
'Illuminate\Auth\Events\Registered' => [
'App\Listeners\LogRegisteredUser',
],
'Illuminate\Auth\Events\Attempting' => [
'App\Listeners\LogAuthenticationAttempt',
],
'Illuminate\Auth\Events\Authenticated' => [
'App\Listeners\LogAuthenticated',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
'Illuminate\Auth\Events\Failed' => [
'App\Listeners\LogFailedLogin',
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogSuccessfulLogout',
],
'Illuminate\Auth\Events\Lockout' => [
'App\Listeners\LogLockout',
],
];
добавлено в 5.2 ()
/**
* Сопоставления слушателя событий для вашего приложения.
*
* @var array
*/
protected $listen = [
'Illuminate\Auth\Events\Attempting' => [
'App\Listeners\LogAuthenticationAttempt',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogSuccessfulLogout',
],
'Illuminate\Auth\Events\Lockout' => [
'App\Listeners\LogLockout',
],
];
/**
* Регистрация любых других событий для вашего приложения.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
// Возникает при каждой попытке аутентификации...
$events->listen('auth.attempt', function ($credentials, $remember, $login) {
//
});
// Возникает при успешных входах...
$events->listen('auth.login', function ($user, $remember) {
//
});
// Возникает при выходах...
$events->listen('auth.logout', function ($user) {
//
});
}
Комментарии (3)
Их нет в текущей версии Laravel, убрали?
Команда php artisan make:auth вернёт всё на место.
Устарел перевод. В английской версии роуты указаны, я думал тут надо самому додумывать. А оказалось перевод к старой версии перевода.