Для фреймворка система безопасности является очень важной частью. Если фреймворк не имеет хороших мер и функций безопасности, то он все равно будет более или менее неудобным при запуске в Интернете. В конце концов, разные большие парни могут в любое время сканировать различные веб-сайты на наличие уязвимостей. Возможно, в прошлом вы не сталкивались с различными инцидентами, связанными с безопасностью, но наверняка слышали о них. Сегодня давайте посмотрим Laravel в Связанные с безопасностью Функция。
существовать Laravel , поставляется с набором логинов пользователей системы сертификации, эта система оказалась непосредственно Фреймворком поставляется с, сейчас существуют, лишенные laravel/jetstream Компонент реализован. По умолчанию мы устанавливаем Laravel После создания фреймворка он будет иметь настройки по умолчанию. User Model ,этот Model Это класс модели пользовательской таблицы по умолчанию.
composer require laravel/jetstream
// использовать Livewire установка стека Jetstream...
php artisan jetstream:install livewire
// использовать Inertia установка стека Jetstream...
php artisan jetstream:install inertia
composer require laravel/sanctum
npm install && npm run dev
С помощью этих трех кодов командной строки мы можем установить компоненты, связанные с Jetstream. После завершения установки он будет иметь интерфейс маршрутизации и просмотра. Мы сможем получить доступ к пути /register, и возвращенный интерфейс будет выглядеть следующим образом.
Это есть система генерирует для нас интерфейс, если мы просматриваем его, когда этот route/web.php из Если вы не видите никакой информации о маршрутизации, то ее маршрут существует. Где определен из? На самом деле это через /vendor/laravel/fortify/src/FortifyServiceProvider.php в configureRoutes() Способ добавления этого поставщика услуг: vendor/laravel/framework/src/Illuminate/Foundation/Application.php Класс контейнерасуществовать registerConfiguredProviders() загружен. Последнее, что на самом деле загружено, это vendor/laravel/fortify/routes/routes.php Это файл маршрутизации.
// ……
if (Features::enabled(Features::registration())) {
if ($enableViews) {
Route::get('/register', [RegisteredUserController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('register');
}
Route::post('/register', [RegisteredUserController::class, 'store'])
->middleware(['guest:'.config('fortify.guard')]);
}
// ……
существуетэтот файл, мы также можем видеть login、logout、user Связано с маршрутизацией операций. Так где же он из шаблона существования? На самом деле, вышеизложенное npm run dev Операция заключается в компиляции Laravel Фреймворк поставляется с Vue framework, а шаблон занимает ровно Vue ,документсуществовать resource/js/Pages ,здесь существуют,мы можем найти Auth/Register.vue Просто измените этот файл и запустите его снова. npm run dev Перекомпилируйте, и вы увидите измененное содержимое. Может быть, есть другой способ, вы можете использовать обычную форму страницы прямого вывода, потому что view/auth Ниже также были сгенерированы некоторые файлы. Сначала я подумал, что это файлы внешнего интерфейса, но оказалось, что это не так. Мы не будем углубляться в это дальше.
Это напрягает? На самом деле, это довольно трудоемко, если его разрабатывает официальная команда компании, ребята из фронтенда не будут компилировать или писать код в вашем фреймворке Laravel. Поэтому эта функция больше подходит для ситуаций, когда мы одни отвечаем за разработку полного набора серверных страниц. Скажем прямо, это очень удобно при выполнении частной работы.
Однако в большинстве случаев мы предпочитаем использовать vue scaffolding, чтобы полностью разделить переднюю и заднюю части, поэтому каждый должен понимать функцию этой части. Далее посмотрим, как реализовать эти операции регистрации и входа самостоятельно, в виде интерфейсов. (То же самое относится и к веб-страницам)
На самом деле очень просто реализовать регистрацию входа самостоятельно. Если это просто вход на веб-страницу, мы все равно используем таблицу данных пользователей, поставляемую с Laravel, а затем настраиваем несколько маршрутов и контроллеров.
class LoginController extends \App\Http\Controllers\Controller
{
public function register(){
return User::create([
'name' => request()->input('name', ''),
'password' => Hash::make(request()->input('password', '')),
]);
}
public function login(){
$name = request()->input('name', '');
$password = request()->input('password', '');
$attempt = Auth::attempt(['name' => $name, 'password' => $password]);
$user = Auth::user();
dd($user, $attempt, $user->api_token);
}
public function info(){
dd(Auth::user());
}
}
существоватьэтотв контроллере,нассуществовать Login используется в методе attempt() Чтобы реализовать функцию входа в систему, вам нужно только передать исходное имя пользователя и пароль. Метод выполнит внутренний запрос пользователя и сравнит его. По умолчанию он использует. User этот Model , вызываемая таблица данных users поверхность. После успешного входа в систему семена будут посажены напрямую. Session и Cookie , вы можете проверить возвращенный запрос самостоятельно Cookie информацию и найдите свою систему сохраненной Session данные.
Route::get('/custom/login', [\App\Http\Controllers\Auth\LoginController::class, 'login']);
Route::get('/custom/register', [\App\Http\Controllers\Auth\LoginController::class, 'register']);
Route::get('/custom/info', [\App\Http\Controllers\Auth\LoginController::class, 'info'])->middleware('auth');
существующий маршрут, мы отдаем последний изэтот info Добавлено промежуточное программное обеспечение, если оно недоступно при запросе. Cookie информацию, то она вернется 403 Непроверенная информация. Вы можете попробовать это сами. Далее мы рассмотрим, как его использовать. token выполнять api из Авторизоватьсяи Контроль аутентификации。Обычно,нас可能会использовать jwt или passport Для этого можно использовать такой плагин api из функции аутентификации. Однако это содержимое выходит за рамки нашего сегодняшнего обсуждения, мы просто посмотрим на стандартное Laravel Как использовать встроенную аутентификацию.
По умолчанию Ларавел Хотя структура обеспечивает Api функцию проверки, но нам все равно нужно добавить некоторый контент вручную, например, в базу данных необходимо добавить api_token из varchar поле, дай его 80 左右из Только длина。然后нас改造一下Авторизоватьсяи Промежуточное ПО проверки маршрута。
public function login(){
$name = request()->input('name', '');
$password = request()->input('password', '');
$attempt = Auth::attempt(['name' => $name, 'password' => $password]);
$user = Auth::user();
$user->api_token = Str::random(60);
$user->save();
// dd($user, $attempt, $user->api_token);
}
существующий логин, нам нужно только создавать новый каждый раз при существовании входа в систему. api_token и сохраните его в данных. Затем будет сгенерирован изэтот api_token Вернитесь на переднюю часть для хранения.
Route::get('/custom/info', [\App\Http\Controllers\Auth\LoginController::class, 'info'])->middleware('auth:api');
Затем info этот тестовый интерфейс из промежуточного программного обеспечения заменен на Фреймворк поставляется с auth:api Вот и все. Далее вы сможете проверить эффект самостоятельно, посетив сайт существования. /custom/info этот интерфейс, вы можете передать его двумя способами api_token 。
существовать Laravel из Система сертификации, промежуточное программное обеспечение имеет защиту от обязанностей, включая существующий файл конфигурации и Auth из Доступны широко используемые методы guard Появляется слово этот. В нашем существующем исходном коде мы в основном смотрим на то, как промежуточное программное обеспечение выполняет аутентификацию и защиту.
Рамка app\Middleware\Authenticate Унаследовано от vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php метод, среди которых handle() В конечном итоге метод вызова authenticate() метод.
protected function authenticate($request, array $guards)
{
if (empty($guards)) {
$guards = [null];
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
$this->unauthenticated($request, $guards);
}
этот метод внутренне вызовет auth объект из grard() Методы продолжают вызываться по цепочке check() Метод определения того, вошел ли пользователь в систему. это auth Объект на самом деле vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php объект. Мы можем ввести шаблон этого класса для просмотра. guard() метод.
public function guard($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);
}
Когда существование создает движущую силу, оно будет основано на нашем существовании. config/auth.php в настройке укажите вызов драйвера, например web вызовизда SessionGuard ,и api будет вызван TokenGuard, здесь изпоколение драйверовинас之前看过из Драйверы кэша очень похожи на,Вы можете посмотреть сами,Наконец, на самом деле есть объединяет содержимое файла конфигурации в имя класса и получает экземпляр объекта. Мы продолжаем TokenGuard Посмотрите пример ниже.
public function __construct(
UserProvider $provider,
Request $request,
$inputKey = 'api_token',
$storageKey = 'api_token',
$hash = false)
{
$this->hash = $hash;
$this->request = $request;
$this->provider = $provider;
$this->inputKey = $inputKey;
$this->storageKey = $storageKey;
}
vendor/laravel/framework/src/Illuminate/Auth/TokenGuard.php из конструктора указывает из по умолчанию key то есть api_token , теперь мы понимаем, почему поле «из», добавленное в нашу базу данных существования, должно быть api_token это поле сейчас. проверять() методсуществовать TokenGuard Так что используйтеиз этого GuardHelpers объект свойств, затем он вызовет user() метод.
public function user()
{
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$user = null;
$token = $this->getTokenForRequest();
if (! empty($token)) {
$user = $this->provider->retrieveByCredentials([
$this->storageKey => $this->hash ? hash('sha256', $token) : $token,
]);
}
return $this->user = $user;
}
public function getTokenForRequest()
{
$token = $this->request->query($this->inputKey);
if (empty($token)) {
$token = $this->request->input($this->inputKey);
}
if (empty($token)) {
$token = $this->request->bearerToken();
}
if (empty($token)) {
$token = $this->request->getPassword();
}
return $token;
}
существоватьэтотметод内部,Встретимся снова getTokenForRequest() Чтобы получить параметры запроса в api_token параметр,Если существованиеиз не сохранено,воляиспользовать request из bearerToekn() Метод получения существующей информации заголовка Authorization данные.这也данасиспользовать api Метод можно передать двумя способами token из-за причины. Наконец, получив из token вызов UserProvider Поставщик услуг получает информацию о пользователе для завершения аутентификации и принятия решения при входе в систему. Весь процесс защиты аутентификации завершен.
Для шифрования, Laravel рамка прямаяиспользоватьизто есть OpenSSL Предоставить из AES-256 и AES-128 шифрование. Также естьобъяснять,этотпо умолчаниюизшифрование Функцияиспользоватьизда Симметричное шифрование из формы. существование Мы узнали раньше PHP в шифровании тоже OpenSSL изшифрование,Симметричное шифрование - это необходимость в ключе, этот ключ на самом деле то естьнассуществовать После установки фреймворкаиспользовать php artisan key:generate Сгенерируйте этот ключ, и он будет сохранен. .env в файле. Эта команда — наша первая статья, которую мы собираем. Laravel Я видел из во время рамок.
все Laravel шифрование之后из Результат будетиспользовать消息认证码 (MAC) знак,Чтобы базовое значение не могло быть изменено снова после шифрования. поэтому,最好建议даиспользовать Laravel Встроенный инструмент шифрования.
Route::get('crypt', function(){
$crypt = \Illuminate\Support\Facades\Crypt::encrypt("aaa");
echo $crypt, "<br/>"; // eyJpdiI6IjhqWUthVWZ2TFVYU0NCa2JxMlFMTXc9PSIsInZhbHVlIjoiUHYwdlhidEhINW9mOE5qMk1pTDg2QT09IiwibWFjIjoiYzVkZDQ4NjgxNDY5YWUwNTU4Yzk4NGZkYjRmMzI5MTIxNDU3M2MxMmNlODAwMjAzOGEzMmU0MjFhNThiYzdmNyJ9
echo \Illuminate\Support\Facades\Crypt::decrypt($crypt); // aaa
});
Код теста очень простой, особо сказать нечего, главное есть encrypt() Шифрование decrypt() Расшифруйте эти две функции. Они осознают существование vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php , мне не нужно больше говорить о том, как найти этот класс реализации через фасад. Что касается конкретного содержания реализации, вы можете самостоятельно ознакомиться с этими двумя методами. Если у вас есть какие-либо вопросы, вы можете ознакомиться с тем, что мы узнали ранее. Изучение расширения шифрования PHPизOpenSSL (1): Симметричное шифрованиеhttps://mp.weixin.qq.com/s/mkUjW5MFQyJDFS4YyMdyaA 。
ивышеиз Crypt Шифрование такое же, как Hash фасадиспользоватьизна самом делето есть password_hash() из метода шифрования, Laravel Это просто его инкапсуляция.
Route::get('hash', function(){
$hash1 = \Illuminate\Support\Facades\Hash::make("aaa");
$hash2 = \Illuminate\Support\Facades\Hash::make("aaa", [
'rounds' => 7,
'memory' => 1024,
'time' => 2,
'threads' => 2,
]);
echo $hash1, "<br/>", $hash2, "<br/>";
// $2y$10$Ga3mtVuosSEkMztnA6TRleJZL6JqNCnT.sQHbw.jdUrmg1o.NPqDO
// $2y$07$B1wLnF/5gjMH/GGY/KaYbu7WVdWIvswBcuORAQRsyfxJ46xyOVTOW
echo \Illuminate\Support\Facades\Hash::check('aaa', $hash1), "<br/>"; // 1
echo \Illuminate\Support\Facades\Hash::check('aaa1', $hash1), "<br/>"; //
echo \Illuminate\Support\Facades\Hash::needsRehash($hash1), "<br/>"; //
});
О результатах теста и параметрах много говорить не буду. Исходный код можно посмотреть самостоятельно. Найти Make() очень легко. Нижний слой есть password_hash() ,check() Нижний слой есть password_verify() ,и needsRehash() Нижний слой есть password_needs_rehash() . для password_hash() Если у вас есть какие-либо вопросы, вы также можете обратиться к нашим предыдущим исследованиям. Алгоритм хеширования паролей PHP — обучение https://mp.weixin.qq.com/s/d_qI3GKB-DoNrBNb7r_LaA Просмотрите его еще раз.
Что касается инъекции, нас больше всего беспокоит не что иное, как есть две проблемы впрыска, одна SQL инъекция, одна XSS инъекция. для SQL инъекция,пока тыиспользоватьрамкаиз построитель запросов или Модель . В принципе особых проблем с инъекциями не будет. Конечно, предполагается не использовать его напрямую. DB::select() Этот способ из написан вами и пишется из SQL заявление.
И для XSS Что насчет? Хотя некоторые операции по обеспечению безопасности выполняются по умолчанию, когда существуют выходные данные шаблона, если получаемые нами параметры сохраняются в базе данных, могут существовать типы хранения. XSS изскрытыйсуществоватьриск。этот东西рамка没有提供直接из解决Функция,каждый можетиспользовать HtmlPurifier решить это напрямую Composer Просто установите его.
Сегодняшний контент в основном посвящен обсуждению Laravel Платформа поставляется с функциями аутентификации и контентом, связанным с шифрованием. На самом деле, чаще всего мы делаем это сами. api формаизинтерфейсили自己去写Авторизоваться页面ипроверятьизлогика。毕竟对于大多数项目来объяснять,Пользовательская таблицаиз Это может быть не такирамка所Предоставить из Точно то же самое,Многие поля также могут отличаться. Тем не менее, оригинальный модуль аутентификации по-прежнему очень прост в использовании.,Вы можете попробовать больше. Что касается знаний, связанных с шифрованием, вы можете просмотреть наши предыдущие статьи и самостоятельно найти соответствующую информацию. Эти вещи универсальны,На самом деле фреймворк может сделать очень многое.
Справочная документация:
https://learnku.com/docs/laravel/8.5/authentication/10397