Аутентификация в Laravel
Аутентификация
это процесс регистрации и логина пользователей. Не путать с авторизацией
проверкой прав уже залогиненного пользователя. В Laravel сделать аутентификацию очень просто — почти всё готово из коробки. Конфигурационный файл аутентификации расположен в config/auth.php
, он содержит несколько опций для тонкой настройки служб аутентификации. По сути средства аутентификации Laravel состоят из гардов
и провайдеров
:
Гарды
определяют как именно аутентифицируются пользователи, для каждого запроса. Laravel поставляется с гардомsession
, который поддерживает состояние аутентифицированности с помощью хранилища сессий и кукПровайдеры
определяют как именно пользователи извлекаются из базы данных. Laravel поставляется с поддержкой извлечения пользователей с помощьюEloquent
иконструктора запросов БД
. При необходимости, можно определить дополнительные провайдеры:
config/auth.php<?php
return [
/*
|--------------------------------------------------------------------------
| Проверка подлинности по умолчанию
|--------------------------------------------------------------------------
|
| Этот параметр управляет аутентификацией по умолчанию "guard" и паролем
| сбросьте параметры для вашего приложения. Вы можете изменить эти значения по умолчанию
| по мере необходимости, но они являются идеальным началом для большинства приложений.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Средства защиты от аутентификации
|--------------------------------------------------------------------------
|
| Далее вы можете определить все средства аутентификации для своего приложения.
| Конечно, для вас была определена отличная конфигурация по умолчанию
| здесь, который использует хранилище сеансов и Eloquentuserprovider.
|
| У всех драйверов аутентификации есть поставщик пользователя. Это определяет, как
| пользователи фактически извлекаются из вашей базы данных или другого хранилища
| механизмы, используемые этим приложением для сохранения данных вашего пользователя.
|
| Поддерживаемый: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| Поставщики услуг для пользователей
|--------------------------------------------------------------------------
|
| У всех драйверов аутентификации есть поставщик пользователя. Это определяет, как
| пользователи фактически извлекаются из вашей базы данных или другого хранилища
| механизмы, используемые этим приложением для сохранения данных вашего пользователя.
|
| Если у вас есть несколько пользовательских таблиц или моделей, вы можете настроить несколько
| источники, которые представляют каждую модель / таблицу. Эти источники могут затем
| быть назначены любым дополнительным средствам аутентификации, которые вы определили.
|
| Поддерживаемый: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Сброс паролей
|--------------------------------------------------------------------------
|
| Вы можете указать несколько конфигураций сброса пароля, если у вас есть больше
| более одной пользовательской таблицы или модели в приложении, и вы хотите иметь
| отдельные настройки сброса пароля в зависимости от конкретных типов пользователей.
|
| Время истечения срока действия - это количество минут, в течение которых каждый токен сброса будет
| считается действительным. Эта функция безопасности сохраняет токены недолговечными, поэтому
| у них меньше времени на то, чтобы быть угаданными. Вы можете изменить это по мере необходимости.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Тайм-аут подтверждения пароля
|--------------------------------------------------------------------------
|
| Здесь вы можете определить количество секунд до подтверждения пароля
| время ожидания истекает, и пользователю предлагается повторно ввести свой пароль через
| экран подтверждения. По умолчанию тайм-аут длится три часа.
|
*/
'password_timeout' => 10800,
];
Session
Из коробки аутентификация в Laravel строится на сессиях, файлы с кешем ссесий храняться в директории storage/framework/sessions
.
Создание заготовок
Для создания заготовок всех необходимых для аутентификации контроллеров, шаблонов и роутов предназначен пакет laravel/ui
:
composer require laravel/ui --dev
php artisan ui:auth
npm install && npm run dev
Будут созданы контроллеры:
RegisterController
обеспечивает регистрацию пользователейLoginController
обеспечивает аутентификацию пользователейForgotPasswordController
отправляет письмо на сброс пароляResetPasswordController
содержит логику для сброса паролей
Будут созданы шаблоны:
auth.register
форма регистрации пользователейauth.login
форма аутентификации пользователейauth.passwords.email
форма для ввода адреса почты (восстановление пароля)auth.passwords.reset
форма для ввода нового пароля (восстановление пароля)
Будут добавлены маршруты, вызов Auth::routes()
добавляет сразу около десятка маршрутов, посмотреть эти маршруты можно в классе Laravel\Ui\AuthRouteMethods
:
routes/web.phpAuth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
vendor/laravel/ui/src/AuthRouteMethods.php<?php
namespace Laravel\Ui;
class AuthRouteMethods
{
/**
* Register the typical authentication routes for an application.
*
* @param array $options
* @return callable
*/
public function auth()
{
return function ($options = []) {
$namespace = class_exists($this->prependGroupNamespace('Auth\LoginController')) ? null : 'App\Http\Controllers';
$this->group(['namespace' => $namespace], function() use($options) {
// Login Routes...
if ($options['login'] ?? true) {
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
}
// Logout Routes...
if ($options['logout'] ?? true) {
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
}
// Registration Routes...
if ($options['register'] ?? true) {
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');
}
// Password Reset Routes...
if ($options['reset'] ?? true) {
$this->resetPassword();
}
// Password Confirmation Routes...
if ($options['confirm'] ??
class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {
$this->confirmPassword();
}
// Email Verification Routes...
if ($options['verify'] ?? false) {
$this->emailVerification();
}
});
};
}
/**
* Register the typical reset password routes for an application.
*
* @return callable
*/
public function resetPassword()
{
return function () {
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
};
}
/**
* Register the typical confirm password routes for an application.
*
* @return callable
*/
public function confirmPassword()
{
return function () {
$this->get('password/confirm', 'Auth\ConfirmPasswordController@showConfirmForm')->name('password.confirm');
$this->post('password/confirm', 'Auth\ConfirmPasswordController@confirm');
};
}
/**
* Register the typical email verification routes for an application.
*
* @return callable
*/
public function emailVerification()
{
return function () {
$this->get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
$this->get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')->name('verification.verify');
$this->post('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
};
}
}
Контроллеры
RegisterController
Контроллер RegisterController
в сочетании с трейтом RegistersUsers
показывает форму регистрации, проводит валидацию данных и создает нового пользователя и выполняет редирект на страницу название_сайта.com/home
. Свойство $redirectTo
определяет, куда будет перенаправлен пользователь после регистрации. Метод validator()
определяет способ валидации регистрационных данных. А метод create()
— как создать нового пользователя на основе полученных регистрационных данных:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller {
use RegistersUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct() {
$this->middleware('guest');
}
protected function validator(array $data) {
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data) {
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
namespace Illuminate\Foundation\Auth;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
trait RegistersUsers {
use RedirectsUsers;
public function showRegistrationForm() {
return view('auth.register');
}
public function register(Request $request) {
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
if ($response = $this->registered($request, $user)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 201)
: redirect($this->redirectPath());
}
protected function guard() {
return Auth::guard();
}
protected function registered(Request $request, $user) {
// .....
}
}
LoginController
Контроллер LoginController
позволяет пользователю выполнить вход в систему. Он подгружает трейт AuthenticatesUsers
, подгружает RedirectUsers
и ThrottlesLogins
который запрещает использовать форму входа пользователям с большим количеством неудачных попыток входа.. Свойство $redirectTo
определяет, куда будет перенаправлен пользователь после аутентификации:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller {
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct() {
$this->middleware('guest')->except('logout');
}
}
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
trait AuthenticatesUsers {
use RedirectsUsers, ThrottlesLogins;
public function showLoginForm() {
return view('auth.login');
}
public function login(Request $request) {
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
protected function validateLogin(Request $request) {
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
protected function attemptLogin(Request $request) {
return $this->guard()->attempt(
$this->credentials($request), $request->filled('remember')
);
}
protected function credentials(Request $request) {
return $request->only($this->username(), 'password');
}
protected function sendLoginResponse(Request $request) {
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect()->intended($this->redirectPath());
}
protected function authenticated(Request $request, $user) {
// .....
}
protected function sendFailedLoginResponse(Request $request) {
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
public function username() {
return 'email';
}
public function logout(Request $request) {
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect('/');
}
protected function loggedOut(Request $request) {
// .....
}
protected function guard() {
return Auth::guard();
}
}
ResetPasswordController
Контроллер ResetPasswordController
подгружает трейт ResetsPasswords
. Этот трейт показывает форму сброса пароля, метод showResetForm()
, обрабатывает POST-запрос, выполянет валидацию и сбрасывает пароль:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller {
use ResetsPasswords;
protected $redirectTo = RouteServiceProvider::HOME;
}
namespace Illuminate\Foundation\Auth;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
trait ResetsPasswords {
use RedirectsUsers;
public function showResetForm(Request $request, $token = null) {
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
public function reset(Request $request) {
$request->validate($this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
protected function rules() {
return [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:8',
];
}
protected function validationErrorMessages() {
return [];
}
protected function credentials(Request $request) {
return $request->only(
'email', 'password', 'password_confirmation', 'token'
);
}
protected function resetPassword($user, $password) {
$this->setUserPassword($user, $password);
$user->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
$this->guard()->login($user);
}
protected function setUserPassword($user, $password) {
$user->password = Hash::make($password);
}
protected function sendResetResponse(Request $request, $response) {
if ($request->wantsJson()) {
return new JsonResponse(['message' => trans($response)], 200);
}
return redirect($this->redirectPath())
->with('status', trans($response));
}
protected function sendResetFailedResponse(Request $request, $response) {
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'email' => [trans($response)],
]);
}
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['email' => trans($response)]);
}
public function broker() {
return Password::broker();
}
protected function guard() {
return Auth::guard();
}
}
ForgotPasswordController
Контроллер ForgotPasswordController
подгружает трейт SendsPasswordResetEmails
. Он показывает форму с помощью метода showLinkRequestForm
, обрабатывает POST-запрос с помощию метода sendResetLinkEmail
:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller {
use SendsPasswordResetEmails;
}
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\Validation\ValidationException;
trait SendsPasswordResetEmails {
public function showLinkRequestForm() {
return view('auth.passwords.email');
}
public function sendResetLinkEmail(Request $request) {
$this->validateEmail($request);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$this->credentials($request)
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($request, $response)
: $this->sendResetLinkFailedResponse($request, $response);
}
protected function validateEmail(Request $request) {
$request->validate(['email' => 'required|email']);
}
protected function credentials(Request $request) {
return $request->only('email');
}
protected function sendResetLinkResponse(Request $request, $response) {
return $request->wantsJson()
? new JsonResponse(['message' => trans($response)], 200)
: back()->with('status', trans($response));
}
protected function sendResetLinkFailedResponse(Request $request, $response) {
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'email' => [trans($response)],
]);
}
return back()
->withInput($request->only('email'))
->withErrors(['email' => trans($response)]);
}
public function broker() {
return Password::broker();
}
}
HomeController
Контроллер HomeController
— после ввода логина и пароля пользователь будет отправлен на эту страницу:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function index() {
return view('home');
}
}
Шаблоны
Шаблон формы для регистрации resources/views/auth/register.blade.php
:
resources/views/auth/register.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">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror"
name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">
{{ __('E-Mail Address') }}
</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror"
name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">
{{ __('Password') }}
</label>
<div class="col-md-6">
<input id="password" type="password" name="password" autocomplete="new-password"
required class="form-control @error('password') is-invalid @enderror">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">
{{ __('Confirm Password') }}
</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control"
name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Шаблон формы для аутентификации (ввод логина и пароля) resources/views/auth/login.blade.php
:
resources/views/auth/login.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">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">
{{ __('E-Mail Address') }}
</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror"
name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">
{{ __('Password') }}
</label>
<div class="col-md-6">
<input id="password" type="password" name="password" autocomplete="current-password"
required class="form-control @error('password') is-invalid @enderror">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember"
id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Шаблон формы для ввода адреса почты при сбросе пароля resources/views/auth/password/reset.blade.php
:
resources/views/auth/password/reset.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">{{ __('Reset Password') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">
{{ __('E-Mail Address') }}
</label>
<div class="col-md-6">
<input id="email" type="email" name="email" value="{{ $email ?? old('email') }}"
class="form-control @error('email') is-invalid @enderror"
required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">
{{ __('Password') }}
</label>
<div class="col-md-6">
<input id="password" type="password" name="password" autocomplete="new-password"
required class="form-control @error('password') is-invalid @enderror">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">
{{ __('Confirm Password') }}
</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control"
name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Reset Password') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Шаблон формы для ввода нового пароля при сбросе пароля resources/views/auth/password/email.blade.php
:
resources/views/auth/password/email.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">{{ __('Reset Password') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{ route('password.email') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">
{{ __('E-Mail Address') }}
</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror"
name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Send Password Reset Link') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Проверка
Теперь пользователи могут регистрироваться и аутентифицироваться:
http://название_сайта.com/register
форма регистрации нового пользователяhttp://название_сайта.com/home
перенаправление после успешной аутентификации пользователяhttp://название_сайта.com/login
вход в системуhttp://название_сайта.com/password/reset
форма для восстановления пароля
Перевод на русский язык
Чтобы не переводить все вручную, можно взять готовый перевод, для этого надо установить пакет:
composer require laravel-lang/lang:~9.0
В config/app.php
изменить locale
:
'locale' => 'ru'
Создаем в папке resources
путь lang
и переносим директорию vendor/laravel-lang/lang/locales/ru
.
Должно получится resources/lang/ru
, из этой дириктории переносим файл ru.json
в директорию resources/lang
.
resources/lang/ru/auth.phpreturn [
/*
|--------------------------------------------------------------------------
| Языковые ресурсы аутентификации
|--------------------------------------------------------------------------
|
| Следующие языковые ресурсы используются во время аутентификации для
| различных сообщений которые мы должны вывести пользователю на экран.
| Вы можете свободно изменять эти языковые ресурсы в соответствии
| с требованиями вашего приложения.
|
*/
'failed' => 'Неверное имя пользователя или пароль.',
'throttle' => 'Слишком много попыток входа. Пожалуйста, попробуйте еще раз через :seconds секунд.',
];
resources/lang/ru/passwords.phpreturn [
/*
|--------------------------------------------------------------------------
| Языковые ресурсы напоминания пароля
|--------------------------------------------------------------------------
|
| Последующие языковые строки возвращаются брокером паролей на неудачные
| попытки обновления пароля в таких случаях, как ошибочный код сброса
| пароля или неверный новый пароль.
|
*/
'reset' => 'Ваш пароль был сброшен!',
'sent' => 'Ссылка на сброс пароля была отправлена!',
'throttled' => 'Пожалуйста, подождите перед повторной попыткой.',
'token' => 'Ошибочный код сброса пароля.',
'user' => 'Не удалось найти пользователя с указанным электронным адресом.',
];
resources/lang/ru.json{
"A fresh verification link has been sent to your email address.": "Новая ссылка для подтверждения была отправлена на Ваш email-адрес.",
"All rights reserved.": "Все права защищены.",
"Before proceeding, please check your email for a verification link.": "Прежде чем продолжить, пожалуйста, проверьте ссылку подтверждения в своей электронной почте.",
"click here to request another": "нажмите здесь, чтобы запросить еще раз",
"Confirm Password": "Подтверждение пароля",
"Dashboard": "Главная",
"E-Mail Address": "Адрес почты",
"Error": "Ошибка",
"Forbidden": "Запрещено",
"Forgot Your Password?": "Забыли пароль?",
"Go Home": "Домой",
"Hello!": "Здравствуйте!",
"hi": "привет",
"If you did not create an account, no further action is required.": "Если Вы не создавали учетную запись, никаких дополнительных действий не требуется.",
"If you did not receive the email": "Если Вы не получили письмо",
"If you did not request a password reset, no further action is required.": "Если Вы не запрашивали сброс пароля, то дополнительных действий не требуется.",
"If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser:": "Если у Вас возникли проблемы с кликом по кнопке \":actionText\", скопируйте и вставьте адрес\nв адресную строку браузера:",
"Invalid signature.": "Неверная подпись.",
"Login": "Войти",
"Logout": "Выйти",
"Name": "Имя",
"Not Found": "Не найдено",
"Oh no": "О, нет",
"Page Expired": "Страница устарела",
"Page Not Found": "Страница не найдена",
"Password": "Пароль",
"Please click the button below to verify your email address.": "Пожалуйста, нажмите кнопку ниже, чтобы подтвердить свой адрес электронной почты.",
"Please confirm your password before continuing.": "Пожалуйста, подтвердите Ваш пароль перед продолжением.",
"Regards": "С уважением",
"Register": "Регистрация",
"Remember Me": "Запомнить меня",
"Reset Password": "Сбросить пароль",
"Reset Password Notification": "Уведомление сброса пароля",
"Send Password Reset Link": "Отправить ссылку для сброса пароля",
"Server Error": "Ошибка сервера",
"Service Unavailable": "Сервис недоступен",
"This action is unauthorized.": "Неавторизованное действие.",
"Sorry, the page you are looking for could not be found.": "Извините, страница, которую вы ищете, не найдена.",
"Sorry, you are forbidden from accessing this page.": "Извините, вам запрещено пользоваться этой страницей.",
"Sorry, you are making too many requests to our servers.": "Извините, вы делаете слишком много запросов на наши серверы.",
"Sorry, you are not authorized to access this page.": "К сожалению, у вас нет доступа к этой странице.",
"Sorry, your session has expired. Please refresh and try again.": "К сожалению, срок действия вашей сессии истек. Обновите и повторите попытку.",
"Sorry, we are doing some maintenance. Please check back soon.": "Извините, мы проводим некоторые работы. Пожалуйста, зайдите позже.",
"This password reset link will expire in :count minutes.": "Срок действия ссылки для сброса пароля истекает через :count минут.",
"Toggle navigation": "Переключить навигацию",
"Too Many Attempts.": "Слишком много попыток.",
"Too Many Requests": "Слишком много запросов",
"Unauthorized": "Не авторизован",
"Verify Email Address": "Подтвердить email-адрес",
"Verify Your Email Address": "Подтвердите Ваш email-адрес",
"We won't ask for your password again for a few hours.": "Мы не будем запрашивать Ваш пароль вновь в течение нескольких часов.",
"You are logged in!": "Вы вошли в систему!",
"You are receiving this email because we received a password reset request for your account.": "Вы получили это письмо, потому что мы получили запрос на сброс пароля для Вашей учетной записи.",
"Whoops!": "Упс!",
"Your email address is not verified.": "Ваш email адрес не подтвержден.",
"Whoops, something went wrong on our servers.": "Упс, на наших серверах что-то пошло не так."
}
Роли
Для настройки груп/ролей используется файл app/Providers/AuthServiceProvider.php