Middleware password.confirm
Middleware password.confirm используется для защиты маршрутов,
требующих дополнительного подтверждения личности пользователя.
При обращении к защищённому маршруту пользователь перенаправляется
на страницу подтверждения пароля, где должен ввести свой текущий
пароль. После успешного подтверждения доступ к маршруту открывается
на ограниченное время (по умолчанию 3 часа). Middleware принимает
необязательный параметр - количество минут, в течение которых
подтверждение будет считаться действительным.
Синтаксис
<?php
// В маршрутах
Route::middleware('password.confirm')->group(function () {
// Защищённые маршруты
});
// С указанием времени действия в минутах
Route::middleware('password.confirm:30')->group(function () {
// Подтверждение действительно 30 минут
});
?>
Пример использования в маршрутах
Рассмотрим защиту группы маршрутов с помощью middleware
password.confirm:
<?php
use Illuminate\Support\Facades\Route;
Route::middleware('password.confirm')->group(function () {
Route::get('/settings/security', [SecurityController::class, 'index'])
->name('settings.security');
Route::post('/settings/security/update-password', [SecurityController::class, 'updatePassword'])
->name('settings.update-password');
});
?>
Настройка вида для страницы подтверждения
Laravel автоматически использует представление из папки
resources/views/auth/confirm-password.blade.php.
Создадим шаблон для страницы подтверждения:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Подтверждение пароля</div>
<div class="card-body">
<p>Пожалуйста, подтвердите ваш пароль перед выполнением этого действия.</p>
<form method="POST" action="{{ route('password.confirm') }}">
@csrf
<div class="form-group">
<label for="password">Пароль</label>
<input id="password" type="password"
class="form-control @error('password') is-invalid @enderror"
name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="form-group mb-0">
<button type="submit" class="btn btn-primary">
Подтвердить пароль
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Создание контроллера для обработки подтверждения
Контроллер будет принимать пароль и проверять его с помощью
фасада Hash:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class ConfirmPasswordController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function showConfirmForm()
{
return view('auth.confirm-password');
}
public function confirm(Request $request)
{
$request->validate([
'password' => 'required|string',
]);
if (!Hash::check($request->password, Auth::user()->password)) {
return back()->withErrors([
'password' => 'Введённый пароль неверен.',
]);
}
$request->session()->passwordConfirmed();
return redirect()->intended();
}
}
?>
Пример защиты критических операций
Защитим операцию удаления аккаунта с подтверждением пароля:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AccountController;
Route::delete('/account/delete', [AccountController::class, 'destroy'])
->name('account.delete')
->middleware('password.confirm:15');
?>
Проверка подтверждения в контроллере
В контроллере можно вручную проверить, было ли подтверждение выполнено в течение заданного времени:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AccountController extends Controller
{
public function destroy(Request $request)
{
if (!$request->session()->has('password_confirmed_at')) {
return redirect()->route('password.confirm');
}
$user = Auth::user();
$user->delete();
return redirect('/')->with('status', 'Аккаунт удалён.');
}
}
?>