git a9035e40c56ffdb31ee1d0ccdf83e16c7cc40867
- Введение
- Аутентификация пользователей
- Получение аутентифицированного пользователя
- Ограничение доступа к роутам в приложении
- Аутентификация на основе HTTP Basic
- Напоминание и сброс пароля
- Аутентификация через социальные сети
Laravel позволяет сделать аутентификацию очень простой. Фактически, почти всё уже готово к использованию «из коробки». Настройки аутентификации находятся в файле config/auth.php
, который содержит несколько хорошо документированных опций для настройки механизма аутентификации.
По умолчанию, Laravel использует модель App\User
в каталоге app
. Эта модель может использоваться вместе с драйвером аутентификации на базе Eloquent.
В Laravel уже включены все необходимые миграции для аутентификации, но при самостоятельном создании схемы БД не забудьте про два обязательных поля в таблице user
(или аналогичной):
- поле с паролем длиной минимум в 60 символов,
- поле
remember_token
для хранения идентификаторов «запомнить меня» длиной в 100 символов (можно создать методом$table->rememberToken();
в миграции).
Если ваше приложение не использует Eloquent, вы можете использовать драйвер аутентификации database
, который работает через построитель запросов.
В Laravel уже есть два контроллера, относящиеся к механизму аутентификации. Контроллер AuthController
обрабатывает регистрацию пользователей и вход в приложение, тогда как контроллер PasswordController
содержит механизмы для сброса забытых паролей у существующих пользователей.
Каждый из этих контроллеров использует трейты для подключения необходимых методов. Как правило, вам не нужно менять код этих контроллеров. Шаблоны, используемые этими контроллерами, находятся в каталоге resources/views/auth
и вы можете свободно изменять их так, как вам нужно.
Для редактирования набора полей формы, которую заполняет пользователь при регистрации, необходимо изменить класс App\Services\Registrar
, который так же отвечает за валидацию введённых данных и создание новых пользователей.
Метод validator
класса Registrar
содержит правила валидации для новых пользователей, тогда как метод create
отвечает непосредственно за создание новой записи о пользователе в БД вашего приложения. Вы можете изменять код этих методов при необходимости. Registrar
вызывается в контроллере AuthController
через метод, находящийся в трейте AuthenticatesAndRegistersUsers
.
Если вы не хотите использовать механизм, предоставляемый контроллером AuthController
, то вы должны использовать сервис аутентификации напрямую. Не волнуйтесь, это не сложно! Для начала, давайте посмотрим на метод attempt
:
<?php namespace App\Http\Controllers;
use Auth;
use Illuminate\Routing\Controller;
class AuthController extends Controller {
/**
* Handle an authentication attempt.
*
* @return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
return redirect()->intended('dashboard');
}
}
}
Метод attempt
принимает массив «ключ-значение» в качестве первого аргумента. Значение ключа password
будет захэшировано. Другие значения массива используются для поиска пользователя в таблице БД. В примере выше, пользователь будет выбираться по полю email
. Если пользователь будет найден, то хэшированный пароль из БД будет сравнён с хэшированным значение поля password
из переданного массива. Если два этих хэша совпадут, то для пользователя будет создана новая аутентифицированная сессия.
Метод attempt
возвращает true
, если аутентификация прошла успешно, и false
в противном случае.
Примечание: В примере выше, поле
Метод intended
возвращает пользователя на тот адрес, доступ к которому он хотел получить, прежде чем его поймал фильтр аутентификации. В качестве параметра, в этот метод можно передать резервный адрес, если запрашиваемый адрес недоступен.
Вы можете добавить дополнительные условия в аутентификационный запрос:
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1]))
{
// Пользователь существует, не забанен и активен.
}
Для проверки, аутентифицирован ли пользователь в вашем приложении, можно использовать метод check
:
if (Auth::check())
{
// Пользователь аутентифицирован...
}
Если вы хотите разрешить пользователям использовать механизм «запомнить меня», вы можете передать булево значение вторым аргументом в метод attempt
, что позволит сохранить статус аутентификации пользователя либо навсегда, либо до тех пор, пока он сам не выйдет из приложения. Естественно, ваша табличка users
должна содержать колонку remember_token
, которая будет использоваться для хранения токена пользователя.
if (Auth::attempt(['email' => $email, 'password' => $password], $remember))
{
// Пользователь будет «запомнен»...
}
Если вы «запоминаете» пользователя, то можете использовать метод viaRemember
чтобы определить, был ли пользователь аутентифицирован с использованием этого механизма:
if (Auth::viaRemember())
{
//
}
Для аутентификации пользователя по его ID существует метод loginUsingId
:
Auth::loginUsingId(1);
Метод validate
позволяет проверить права пользователя без фактической аутентификации:
if (Auth::validate($credentials))
{
//
}
Метод once
служит для аутентификации пользователя на время выполнения текущего запроса, при этом не используются сессия и куки:
if (Auth::once($credentials))
{
//
}
Для принудительной аутентифицикации пользователя существует метод login
:
Auth::login($user);
Это эквивалентно аутентификации с использованием метода attempt
и передачей параметров пользователя.
Auth::logout();
Конечно, если вы используете встроенные контроллеры Laravel для аутентификации, то в них всё это уже реализовано.
При вызове метода attempt
запускается событие auth.attempt
. Если аутентификация прошла успешно и пользователь вошёл в приложение, будет запущено событие auth.login
.
Как только пользователь аутентифицирован, вы можете получить объект пользователя несколькими путями.
Во-первых, с помощью фасада Auth
:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
class ProfileController extends Controller {
/**
* Update the user's profile.
*
* @return Response
*/
public function updateProfile()
{
if (Auth::user())
{
// $request->user() возвращает объект пользователя...
}
}
}
Во-вторых, используя метод user
класса Illuminate\Http\Request
:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ProfileController extends Controller {
/**
* Update the user's profile.
*
* @return Response
*/
public function updateProfile(Request $request)
{
if ($request->user())
{
// $request->user() возвращает объект пользователя...
}
}
}
В-третьих, можно использовать мощь сервис-контейнера, указав в качестве аргумента в конструкторе или методе контракт Illuminate\Contracts\Auth\Authenticatable
:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Contracts\Auth\Authenticatable;
class ProfileController extends Controller {
/**
* Update the user's profile.
*
* @return Response
*/
public function updateProfile(Authenticatable $user)
{
// $user - это объект пользователя...
}
}
Вы можете использовать посредников для ограничения доступа к роутам. В Laravel уже есть посредник auth
, который находится в файле app\Http\Middleware\Authenticate.php
. Всё, что вам нужно - указать его в описании нужного роута:
// Если роут описан как замыкание...
Route::get('profile', ['middleware' => 'auth', function()
{
// Доступ разрешён только аутентифицированным пользователям...
}]);
// Или как контроллер...
Route::get('profile', ['middleware' => 'auth', 'uses' => 'ProfileController@show']);
Аутентификация на основе HTTP Basic позволяет аутентифицировать пользователей быстро и без отдельной страницы входа. Для этого надо указать посредника auth.basic
в описании нужного роута:
Route::get('profile', ['middleware' => 'auth.basic', function()
{
// Доступ разрешён только аутентифицированным пользователям...
}]);
По умолчанию, посредник basic
использует поле email
из таблицы пользователей в качестве идентификатора пользователя.
Также можно использовать аутентификацию на основе HTTP Basic без создания сессии и идентификационной куки, что часто используется для аутентификации через API. Для этого нужно создать посредника, который будет вызывать метод onceBasic
:
public function handle($request, Closure $next)
{
return Auth::onceBasic() ?: $next($request);
}
Если вы используете PHP в режиме FastCGI, то аутентификация на основе HTTP Basic может не работать «из коробки». Решается эта проблема добавлением следующих строк в файл .htaccess
:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Большинство веб-приложений позволяют пользователям сбросить забытый пароль. Вместо того, чтобы каждый раз изобретать велосипед, Laravel предоставляет удобный механизм для реализации этой возможности.
Для начала, удостоверьтесь, что ваша модель User
реализует контракт Illuminate\Contracts\Auth\Remindable
в том случае, если вы не используете стандартную модель User
, которая уже реализует этот контракт при помощи трейта Illuminate\Auth\Reminders\Remindable
.
Далее нужно создать таблицу, хранящую токены-напоминания для сброса пароля. Эта миграция уже включена в Laravel и находится в папке database/migrations
. Поэтому всё, что вам нужно сделать, это выполнить команду:
php artisan migrate
Laravel также предоставляет контроллер Auth\PasswordController
, который содержит всю логику для работы со сбросом паролей и конечно же имеются начальные шаблоны! Шаблоны находятся в папке resources/views/auth
и вы можете изменять их так, как вам нужно.
Пользователь получает письмо со ссылкой, обрабатываемой методом getReset
в контроллере PasswordController
. Это метод отображает форму, где пользователь указывает новый пароль. После этого пользователь автоматически аутентифицируется и перенаправляется на адрес /home
. Вы можете задать свой адрес в свойстве redirectTo
контроллера PasswordController
:
protected $redirectTo = '/dashboard';
Примечание: По умолчанию, срок жизни токена ограничен одним часом. Вы можете изменить это, указав нужное время в опции
reminder.expire
в файлеconfig/auth.php
.
В добавок к обычной аутентификации, с помощью форм и HTTP Basic, Laravel предоставляет простой и удобный механизм аутентификации через OAuth, используя Laravel Socialite. Socialite пока что поддерживает аутентификацию только через Facebook, Twitter, Google и GitHub.
Чтобы начать использовать Socialite, добавьте этот пакет в ваш файл composer.json
:
"laravel/socialite": "~2.0"
После, зарегистрируйте провайдер Laravel\Socialite\SocialiteServiceProvider
в файле config/app.php
. Вы также можете зарегистрировать фасад Socialize
:
'Socialize' => 'Laravel\Socialite\Facades\Socialite',
Далее вам необходимо указать параметры для того сервиса OAuth, который вы используете. Это можно сделать в файле config/services.php
. Пока доступно четыре сервиса: facebook
, twitter
, google
и github
. Пример:
'github' => [
'client_id' => 'your-github-app-id',
'client_secret' => 'your-github-app-secret',
'redirect' => 'http:https://your-callback-url',
],
После этого нужно добавить два роута: один для перенаправления пользователя к провайдеру OAuth, второй для получения ответа от провайдера после аутентификации пользователя. Пример с использованием фасада Socialize
:
public function redirectToProvider()
{
return Socialize::with('github')->redirect();
}
public function handleProviderCallback()
{
$user = Socialize::with('github')->user();
// $user->token;
}
Метод redirect
выполнит перенаправление к провайдеру OAuth, а метод user
получит информацию о пользователе из ответа провайдера OAuth. Перед перенаправлением, вы можете указать области доступа:
return Socialize::with('github')->scopes(['scope1', 'scope2'])->redirect();
Как только вы получите объект пользователя, можно получить пользовательские данные:
$user = Socialize::with('github')->user();
// Провайдеры, использующие OAuth v.2.0
$token = $user->token;
// Провайдеры, использующие OAuth v.1.0
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// Все провайдеры
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();