Версия фреймворка: 5.4 4.2

Безопасность

Конфигурация

Laravel стремится сделать реализацию авторизации максимально простой. Фактически, после установки фреймворка почти всё уже настроено. Настройки хранятся в файле app/config/auth.php, который содержит несколько хорошо документированных параметров для настройки поведения методов аутентификации.

"Из коробки" приложение Laravel включает в себя модель User в папке app/models, которая может использоваться вместе с дефолтным драйвером аутентификации Eloquent. При создании таблицы для данной модели убедитесь, что поле пароля принимает как минимум 60 символов.

Если ваше приложение не использует Eloquent, вы можете использовать драйвер database, который использует конструктор запросов Laravel.

Примечание: Перед тем как начать, пожалуйста, убедитесь, что таблица users (или другая, в которой хранятся пользователи) содержит nullable (с возможностью содержать NULL) столбец remember_token длиною 100 символов (VARCHAR(100)). Этот столбец испольдуется для хранения токена, когда пользователь при логине ставит галку "запомнить меня".

Хранение паролей

Класс 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, который он пытался просмотреть до того, как запрос был перехвачен фильтром аутентификации. Также в этом методе можно задать дополнительный URL, куда будет осуществлен переход, если первый URL не доступен.

Когда вызывается метод attempt, запускается событие auth.attempt. При успешной авторизации также запускается событие auth.login.

Проверка авторизации пользователя

Для определения того, авторизован ли пользователь или нет, можно использовать метод check.

if (Auth::check())
{
	// Пользователь уже вошёл в систему
}

Если вы хотите предоставить функциональность типа "запомнить меня", то вы можете передать true вторым параметром к методу attempt, который будет поддерживать авторизацию пользователя без ограничения по времени (пока он вручную не выйдет из системы). В такоем случае у вашей таблицы users должен быть строковой столбец remember_token для хранения токена пользователя.

if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
	// Пользователь был запомнен
}

Примечание: если метод attempt вернул true, то пользователь успешно вошёл в систему.

Имеет ли пользователь токен "запомнить меня"

Метод viaRemember позволяет узнать, вошел ли пользователь при помощи фичи "запомнить меня".

if (Auth::viaRemember())
{
	// Пользователь вошел, так как ранее ставил галку "запомнить меня"
}

Авторизация пользователя с использованием условий

Вы также можете передать дополнительные условия для запроса к таблице:

if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1)))
{
    // Вход, если пользователь активен, не отключен и существует.
}
Примечание Для повышения безопасности после аутентификации фреймворк регенерирует ID сессии пользователя.

Доступ к залогиненному пользователю

Как только пользователь аутентифицирован, вы можете обращаться к модели User и её свойствам.

$email = Auth::user()->email;

Чтобы получить ID залогиненого пользователя, воспользуйтесь методом id:

$id = Auth::id();

Для простой аутентификации пользователя по ID используется метод loginUsingId:

Auth::loginUsingId(1);

Проверка данных для входа без авторизации

Метод validate позволяет вам проверить данные для входа без осуществления самого входа.

if (Auth::validate($credentials))
{
	//
}

Аутентификация пользователя на один запрос

Вы также можете использовать метод once для авторизации пользователя в системе только для одного запроса. Сессии и cookies не будут использованы.

if (Auth::once($credentials))
{
	//
}

Выход пользователя из приложения

Auth::logout();

Ручная авторизация

Если вам нужно войти существующим пользователем, просто передайте его модель в метод login:

$user = User::find(1);

Auth::login($user);

Это эквивалентно аутентификации пользователя через его данные методом attempt.

Аутентификация и роутинг

Вы можете использовать Фильтры роутов, чтобы позволишь только залогиненным пользователям обращаться к заданному роуту или группе роутов. Изначально Laravel содержит фильтр auth, который содержится в файле app/filters.php.

Защита роута аутентификацией

Route::get('profile', array('before' => 'auth', function()
{
	// Доступно только залогиненным пользователям.
}));

Защита от подделки запросов (CSRF)

Laravel предоставляет простой способ защиты вашего приложения от подделки межсайтовых запросов (cross-site request forgeries, CSRF).

Вставка CSRF-ключа в форму

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

Проверка переданного CSRF-ключа

Route::post('register', array('before' => 'csrf', function()
{
    return 'Вы передали верный ключ!';
}));

HTTP-аутентификация

HTTP Basic Authentication - простой и быстрый способ аутентификации пользователей вашего приложения без создания дополнительной страницы входа. При HTTP-аутентификации форму для ввода логина и пароля показывает браузер, в виде всплывающего окна. Для HTTP-аутентификации используйте фильтр auth.basic:

Защита роута фильтром HTTP-аутентификации

Route::get('profile', array('before' => 'auth.basic', function()
{
	// Доступно только залогиненным пользователям.
}));

По умолчанию, фильтр basic будет использовать поле email модели объекта при аутентификации. Если вы хотите использовать иное поле, можно передать его имя первым параметром методу basic в файле app/filters.php:

Route::filter('auth.basic', function()
{
	return Auth::basic('username');
});

Авторизация без запоминания состояния

Вы можете использовать HTTP-авторизацию без установки cookies в сессии, что особенно удобно для аутентификации в API. Для этого зарегистрируйте фильтр, вовращающий результат вызова onceBasic.

Route::filter('basic.once', function()
{
	return Auth::onceBasic();
});

Если вы используете Apache + PHP FastCGI, HTTP-аутентификация не будет работать "из коробки". Вам нужно добавить следующие строки в свой .htaccess:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Сброс забытого пароля

Модель и таблица

Восстановление забытого пароля - очень распространенная вещь в веб-приложениях. Чтобы не заставлять вас писать его вновь и вновь, Laravel предоставляет встроенные удобные методы для совершения подобных операций. Для начала убедитесь, что ваша модель User реализует (implements) интерфейс Illuminate\Auth\Reminders\RemindableInterface. Модель User, которая идет с фреймворком, уже реализует его - она включает в себя Illuminate\Auth\Reminders\RemindableTrait с методами, которые реализуют этот интерфейс.

Реализация RemindableInterface

use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements RemindableInterface {

	use RemindableTrait;
}

Создание таблицы токенов сброса пароля

Далее, должна быть создана таблица для хранения токенов запросов сброса пароля. Для создания такой таблицы существует artisan-команда auth:reminders-table.

php artisan auth:reminders-table

php artisan migrate

Контроллер восстановления пароля

Чтобы автоматически создать контроллер восстановления пароля, воспользуйтесь командой auth:reminders-controller. В папке controllers будет создан RemindersController.php:

php artisan auth:reminders-controller

Созданный контроллер содержит метод getRemind, который показывает форму для напоминания пароля. Вам надо создать эту форму во вьюхе password.remind (файл remind.blade.php в папке views/password - см. view). Форма должна отправлять POST c email на метод postRemind

Простейший пример password.remind:

<form action="{{ action('RemindersController@postRemind') }}" method="POST">
	<input type="email" name="email">
	<input type="submit" value="Send Reminder">
</form>

Метод postRemind уже есть в сгенеренном RemindersController.php. Приняв email POST-запросом, контроллер отсылает на этот адрес письмо с подтверждением. Если оно отсылается нормально, в сессию во flash-переменную status заносится сообщение об успешной отправке. Если нет - во flash-переменную error заносится текст ошибки.

Для модификации собщения, которое уйдет пользователю на почту, вы можете изменить в контроллере вызов Password::remind на, например, такое:

Password::remind(Input::only('email'), function($message)
{
	$message->subject('Password Reminder');
});

Пользователь получит письмо со ссылкой на метод getReset, с токеном для индентификации пользователя. Этот метод вызывает вьюху password.reset (файл reset.blade.php в папке views/password), в которой должна быть форма для смены пароля, со скрытым полем token и полями email, password, and password_confirmation, например такая:

<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>

Метод postReset производит замену паролей в вашем сторадже. По умолчанию считается, что пользователи хранятся в БД, с которой умеет работать Eloquent - ожидается $user, который передается в функцию-замыкание имеет метод save. Если это не так, измените функцию-замыкание в аргументе Password::reset в контроллере RemindersController исходя из вашей архитектуры приложения.

Если смена пароля прошла удачно, пользователь редиректится на главную страницу вашего приложения (вы можете изменить URL редиректа, если хотите). Если нет - пользователь редиректится обратно с установкой flash-переменной error.

Валидация паролей

По умолчанию Password::reset валидирует пароль пользователя исходя из двух правил - введенные пароли должны совпадать и пароль должен быть больше или равен 6 символам. Если вы хотите расширить валидацию паролей, вы можете определить свой Password::validator:

Password::validator(function($credentials)
{
	return strlen($credentials['password']) >= 6;
});
Примечание Токены сброса пароля валидны в течении одного часа. Вы можете изменить это в app/config/auth.php, параметр reminder.expire.

Шифрование

Laravel предоставляет функции устойчивого шифрования по алгоритму AES с помощью расширения mcrypt для PHP.

Шифрование строки

$encrypted = Crypt::encrypt('секрет');
Примечание: обязательно установите 16, 24 или 32-значный ключ key в файле app/config/app.php. Если этого не сделать, зашифрованные строки не будут достаточно надежными.

Расшифровка строки

$decrypted = Crypt::decrypt($encryptedValue);

Изменение режима и алгоритма шифрования

Вы также можете установить свой алгоритм и режим шифрования:

Crypt::setMode('ctr');

Crypt::setCipher($cipher);

Драйвера аутентификации

Laravel из коробки предлагает для аутентификации драйвера database и eloquent. Чтобы узнать больше о том, как добавлять свои драйвера, изучите документацию по расширению системы аутентификации.