# Laravel Fortify
* Introduction
* What is Fortify?
* When Should I Use Fortify?
* Installation
* Fortify Features
* Disabling Views
* Authentication
* Customizing User Authentication
* Customizing the Authentication Pipeline
* Customizing Redirects
* Two Factor Authentication
* Enabling Two Factor Authentication
* Authenticating With Two Factor Authentication
* Disabling Two Factor Authentication
* Registration
* Customizing Registration
* Password Reset
* Requesting a Password Reset Link
* Resetting the Password
* Customizing Password Resets
* Email Verification
* Protecting Routes
* Password Confirmation
## Introduction
[Laravel Fortify](https://github.com/laravel/fortify) is a frontend agnostic
authentication backend implementation for Laravel. Fortify registers the
routes and controllers needed to implement all of Laravel's authentication
features, including login, registration, password reset, email verification,
and more. After installing Fortify, you may run the `route:list` Artisan
command to see the routes that Fortify has registered.
Since Fortify does not provide its own user interface, it is meant to be
paired with your own user interface which makes requests to the routes it
registers. We will discuss exactly how to make requests to these routes in the
remainder of this documentation.
Remember, Fortify is a package that is meant to give you a head start
implementing Laravel's authentication features. **You are not required to use
it.** You are always free to manually interact with Laravel's authentication
services by following the documentation available in the
[authentication](/docs/12.x/authentication), [password
reset](/docs/12.x/passwords), and [email
verification](/docs/12.x/verification) documentation.
### What is Fortify?
As mentioned previously, Laravel Fortify is a frontend agnostic authentication
backend implementation for Laravel. Fortify registers the routes and
controllers needed to implement all of Laravel's authentication features,
including login, registration, password reset, email verification, and more.
**You are not required to use Fortify in order to use Laravel's authentication
features.** You are always free to manually interact with Laravel's
authentication services by following the documentation available in the
[authentication](/docs/12.x/authentication), [password
reset](/docs/12.x/passwords), and [email
verification](/docs/12.x/verification) documentation.
If you are new to Laravel, you may wish to explore [our application starter
kits](/docs/12.x/starter-kits) before attempting to use Laravel Fortify. Our
starter kits provide an authentication scaffolding for your application that
includes a user interface built with [Tailwind CSS](https://tailwindcss.com).
This allows you to study and get comfortable with Laravel's authentication
features before allowing Laravel Fortify to implement these features for you.
Laravel Fortify essentially takes the routes and controllers of our
application starter kits and offers them as a package that does not include a
user interface. This allows you to still quickly scaffold the backend
implementation of your application's authentication layer without being tied
to any particular frontend opinions.
### When Should I Use Fortify?
You may be wondering when it is appropriate to use Laravel Fortify. First, if
you are using one of Laravel's [application starter kits](/docs/12.x/starter-
kits), you do not need to install Laravel Fortify since all of Laravel's
application starter kits already provide a full authentication implementation.
If you are not using an application starter kit and your application needs
authentication features, you have two options: manually implement your
application's authentication features or use Laravel Fortify to provide the
backend implementation of these features.
If you choose to install Fortify, your user interface will make requests to
Fortify's authentication routes that are detailed in this documentation in
order to authenticate and register users.
If you choose to manually interact with Laravel's authentication services
instead of using Fortify, you may do so by following the documentation
available in the [authentication](/docs/12.x/authentication), [password
reset](/docs/12.x/passwords), and [email
verification](/docs/12.x/verification) documentation.
#### Laravel Fortify and Laravel Sanctum
Some developers become confused regarding the difference between [Laravel
Sanctum](/docs/12.x/sanctum) and Laravel Fortify. Because the two packages
solve two different but related problems, Laravel Fortify and Laravel Sanctum
are not mutually exclusive or competing packages.
Laravel Sanctum is only concerned with managing API tokens and authenticating
existing users using session cookies or tokens. Sanctum does not provide any
routes that handle user registration, password reset, etc.
If you are attempting to manually build the authentication layer for an
application that offers an API or serves as the backend for a single-page
application, it is entirely possible that you will utilize both Laravel
Fortify (for user registration, password reset, etc.) and Laravel Sanctum (API
token management, session authentication).
## Installation
To get started, install Fortify using the Composer package manager:
1composer require laravel/fortify
composer require laravel/fortify
Next, publish Fortify's resources using the `fortify:install` Artisan command:
1php artisan fortify:install
php artisan fortify:install
This command will publish Fortify's actions to your `app/Actions` directory,
which will be created if it does not exist. In addition, the
`FortifyServiceProvider`, configuration file, and all necessary database
migrations will be published.
Next, you should migrate your database:
1php artisan migrate
php artisan migrate
### Fortify Features
The `fortify` configuration file contains a `features` configuration array.
This array defines which backend routes / features Fortify will expose by
default. We recommend that you only enable the following features, which are
the basic authentication features provided by most Laravel applications:
1'features' => [
2 Features::registration(),
3 Features::resetPasswords(),
4 Features::emailVerification(),
5],
'features' => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
],
### Disabling Views
By default, Fortify defines routes that are intended to return views, such as
a login screen or registration screen. However, if you are building a
JavaScript driven single-page application, you may not need these routes. For
that reason, you may disable these routes entirely by setting the `views`
configuration value within your application's `config/fortify.php`
configuration file to `false`:
1'views' => false,
'views' => false,
#### Disabling Views and Password Reset
If you choose to disable Fortify's views and you will be implementing password
reset features for your application, you should still define a route named
`password.reset` that is responsible for displaying your application's "reset
password" view. This is necessary because Laravel's
`Illuminate\Auth\Notifications\ResetPassword` notification will generate the
password reset URL via the `password.reset` named route.
## Authentication
To get started, we need to instruct Fortify how to return our "login" view.
Remember, Fortify is a headless authentication library. If you would like a
frontend implementation of Laravel's authentication features that are already
completed for you, you should use an [application starter
kit](/docs/12.x/starter-kits).
All of the authentication view's rendering logic may be customized using the
appropriate methods available via the `Laravel\Fortify\Fortify` class.
Typically, you should call this method from the `boot` method of your
application's `App\Providers\FortifyServiceProvider` class. Fortify will take
care of defining the `/login` route that returns this view:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::loginView(function () {
9 return view('auth.login');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::loginView(function () {
return view('auth.login');
});
// ...
}
Your login template should include a form that makes a POST request to
`/login`. The `/login` endpoint expects a string `email` / `username` and a
`password`. The name of the email / username field should match the `username`
value within the `config/fortify.php` configuration file. In addition, a
boolean `remember` field may be provided to indicate that the user would like
to use the "remember me" functionality provided by Laravel.
If the login attempt is successful, Fortify will redirect you to the URI
configured via the `home` configuration option within your application's
`fortify` configuration file. If the login request was an XHR request, a 200
HTTP response will be returned.
If the request was not successful, the user will be redirected back to the
login screen and the validation errors will be available to you via the shared
`$errors` [Blade template variable](/docs/12.x/validation#quick-displaying-
the-validation-errors). Or, in the case of an XHR request, the validation
errors will be returned with the 422 HTTP response.
### Customizing User Authentication
Fortify will automatically retrieve and authenticate the user based on the
provided credentials and the authentication guard that is configured for your
application. However, you may sometimes wish to have full customization over
how login credentials are authenticated and users are retrieved. Thankfully,
Fortify allows you to easily accomplish this using the
`Fortify::authenticateUsing` method.
This method accepts a closure which receives the incoming HTTP request. The
closure is responsible for validating the login credentials attached to the
request and returning the associated user instance. If the credentials are
invalid or no user can be found, `null` or `false` should be returned by the
closure. Typically, this method should be called from the `boot` method of
your `FortifyServiceProvider`:
1use App\Models\User;
2use Illuminate\Http\Request;
3use Illuminate\Support\Facades\Hash;
4use Laravel\Fortify\Fortify;
5
6/**
7 * Bootstrap any application services.
8 */
9public function boot(): void
10{
11 Fortify::authenticateUsing(function (Request $request) {
12 $user = User::where('email', $request->email)->first();
13
14 if ($user &&
15 Hash::check($request->password, $user->password)) {
16 return $user;
17 }
18 });
19
20 // ...
21}
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->email)->first();
if ($user &&
Hash::check($request->password, $user->password)) {
return $user;
}
});
// ...
}
#### Authentication Guard
You may customize the authentication guard used by Fortify within your
application's `fortify` configuration file. However, you should ensure that
the configured guard is an implementation of
`Illuminate\Contracts\Auth\StatefulGuard`. If you are attempting to use
Laravel Fortify to authenticate an SPA, you should use Laravel's default `web`
guard in combination with [Laravel Sanctum](https://laravel.com/docs/sanctum).
### Customizing the Authentication Pipeline
Laravel Fortify authenticates login requests through a pipeline of invokable
classes. If you would like, you may define a custom pipeline of classes that
login requests should be piped through. Each class should have an `__invoke`
method which receives the incoming `Illuminate\Http\Request` instance and,
like [middleware](/docs/12.x/middleware), a `$next` variable that is invoked
in order to pass the request to the next class in the pipeline.
To define your custom pipeline, you may use the `Fortify::authenticateThrough`
method. This method accepts a closure which should return the array of classes
to pipe the login request through. Typically, this method should be called
from the `boot` method of your `App\Providers\FortifyServiceProvider` class.
The example below contains the default pipeline definition that you may use as
a starting point when making your own modifications:
1use Laravel\Fortify\Actions\AttemptToAuthenticate;
2use Laravel\Fortify\Actions\CanonicalizeUsername;
3use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
4use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
5use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
6use Laravel\Fortify\Features;
7use Laravel\Fortify\Fortify;
8use Illuminate\Http\Request;
9
10Fortify::authenticateThrough(function (Request $request) {
11 return array_filter([
12 config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
13 config('fortify.lowercase_usernames') ? CanonicalizeUsername::class : null,
14 Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
15 AttemptToAuthenticate::class,
16 PrepareAuthenticatedSession::class,
17 ]);
18});
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\CanonicalizeUsername;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use Illuminate\Http\Request;
Fortify::authenticateThrough(function (Request $request) {
return array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
config('fortify.lowercase_usernames') ? CanonicalizeUsername::class : null,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]);
});
#### Authentication Throttling
By default, Fortify will throttle authentication attempts using the
`EnsureLoginIsNotThrottled` middleware. This middleware throttles attempts
that are unique to a username and IP address combination.
Some applications may require a different approach to throttling
authentication attempts, such as throttling by IP address alone. Therefore,
Fortify allows you to specify your own [rate limiter](/docs/12.x/routing#rate-
limiting) via the `fortify.limiters.login` configuration option. Of course,
this configuration option is located in your application's
`config/fortify.php` configuration file.
Utilizing a mixture of throttling, [two factor
authentication](/docs/12.x/fortify#two-factor-authentication), and an external
web application firewall (WAF) will provide the most robust defense for your
legitimate application users.
### Customizing Redirects
If the login attempt is successful, Fortify will redirect you to the URI
configured via the `home` configuration option within your application's
`fortify` configuration file. If the login request was an XHR request, a 200
HTTP response will be returned. After a user logs out of the application, the
user will be redirected to the `/` URI.
If you need advanced customization of this behavior, you may bind
implementations of the `LoginResponse` and `LogoutResponse` contracts into the
Laravel [service container](/docs/12.x/container). Typically, this should be
done within the `register` method of your application's
`App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Contracts\LogoutResponse;
2
3/**
4 * Register any application services.
5 */
6public function register(): void
7{
8 $this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
9 public function toResponse($request)
10 {
11 return redirect('/');
12 }
13 });
14}
use Laravel\Fortify\Contracts\LogoutResponse;
/**
* Register any application services.
*/
public function register(): void
{
$this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
public function toResponse($request)
{
return redirect('/');
}
});
}
## Two Factor Authentication
When Fortify's two factor authentication feature is enabled, the user is
required to input a six digit numeric token during the authentication process.
This token is generated using a time-based one-time password (TOTP) that can
be retrieved from any TOTP compatible mobile authentication application such
as Google Authenticator.
Before getting started, you should first ensure that your application's
`App\Models\User` model uses the `Laravel\Fortify\TwoFactorAuthenticatable`
trait:
1 By default, the `features` array of the `fortify` configuration file
> instructs Fortify's two factor authentication settings to require password
> confirmation before modification. Therefore, your application should
> implement Fortify's password confirmation feature before continuing.
### Enabling Two Factor Authentication
To begin enabling two factor authentication, your application should make a
POST request to the `/user/two-factor-authentication` endpoint defined by
Fortify. If the request is successful, the user will be redirected back to the
previous URL and the `status` session variable will be set to `two-factor-
authentication-enabled`. You may detect this `status` session variable within
your templates to display the appropriate success message. If the request was
an XHR request, `200` HTTP response will be returned.
After choosing to enable two factor authentication, the user must still
"confirm" their two factor authentication configuration by providing a valid
two factor authentication code. So, your "success" message should instruct the
user that two factor authentication confirmation is still required:
1@if (session('status') == 'two-factor-authentication-enabled')
2
3 Please finish configuring two factor authentication below.
4
5@endif
@if (session('status') == 'two-factor-authentication-enabled')
Please finish configuring two factor authentication below.
@endif
Next, you should display the two factor authentication QR code for the user to
scan into their authenticator application. If you are using Blade to render
your application's frontend, you may retrieve the QR code SVG using the
`twoFactorQrCodeSvg` method available on the user instance:
1$request->user()->twoFactorQrCodeSvg();
$request->user()->twoFactorQrCodeSvg();
If you are building a JavaScript powered frontend, you may make an XHR GET
request to the `/user/two-factor-qr-code` endpoint to retrieve the user's two
factor authentication QR code. This endpoint will return a JSON object
containing an `svg` key.
#### Confirming Two Factor Authentication
In addition to displaying the user's two factor authentication QR code, you
should provide a text input where the user can supply a valid authentication
code to "confirm" their two factor authentication configuration. This code
should be provided to the Laravel application via a POST request to the
`/user/confirmed-two-factor-authentication` endpoint defined by Fortify.
If the request is successful, the user will be redirected back to the previous
URL and the `status` session variable will be set to `two-factor-
authentication-confirmed`:
1@if (session('status') == 'two-factor-authentication-confirmed')
2
3 Two factor authentication confirmed and enabled successfully.
4
5@endif
@if (session('status') == 'two-factor-authentication-confirmed')
Two factor authentication confirmed and enabled successfully.
@endif
If the request to the two factor authentication confirmation endpoint was made
via an XHR request, a `200` HTTP response will be returned.
#### Displaying the Recovery Codes
You should also display the user's two factor recovery codes. These recovery
codes allow the user to authenticate if they lose access to their mobile
device. If you are using Blade to render your application's frontend, you may
access the recovery codes via the authenticated user instance:
1(array) $request->user()->recoveryCodes()
(array) $request->user()->recoveryCodes()
If you are building a JavaScript powered frontend, you may make an XHR GET
request to the `/user/two-factor-recovery-codes` endpoint. This endpoint will
return a JSON array containing the user's recovery codes.
To regenerate the user's recovery codes, your application should make a POST
request to the `/user/two-factor-recovery-codes` endpoint.
### Authenticating With Two Factor Authentication
During the authentication process, Fortify will automatically redirect the
user to your application's two factor authentication challenge screen.
However, if your application is making an XHR login request, the JSON response
returned after a successful authentication attempt will contain a JSON object
that has a `two_factor` boolean property. You should inspect this value to
know whether you should redirect to your application's two factor
authentication challenge screen.
To begin implementing two factor authentication functionality, we need to
instruct Fortify how to return our two factor authentication challenge view.
All of Fortify's authentication view rendering logic may be customized using
the appropriate methods available via the `Laravel\Fortify\Fortify` class.
Typically, you should call this method from the `boot` method of your
application's `App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::twoFactorChallengeView(function () {
9 return view('auth.two-factor-challenge');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::twoFactorChallengeView(function () {
return view('auth.two-factor-challenge');
});
// ...
}
Fortify will take care of defining the `/two-factor-challenge` route that
returns this view. Your `two-factor-challenge` template should include a form
that makes a POST request to the `/two-factor-challenge` endpoint. The `/two-
factor-challenge` action expects a `code` field that contains a valid TOTP
token or a `recovery_code` field that contains one of the user's recovery
codes.
If the login attempt is successful, Fortify will redirect the user to the URI
configured via the `home` configuration option within your application's
`fortify` configuration file. If the login request was an XHR request, a 204
HTTP response will be returned.
If the request was not successful, the user will be redirected back to the two
factor challenge screen and the validation errors will be available to you via
the shared `$errors` [Blade template variable](/docs/12.x/validation#quick-
displaying-the-validation-errors). Or, in the case of an XHR request, the
validation errors will be returned with a 422 HTTP response.
### Disabling Two Factor Authentication
To disable two factor authentication, your application should make a DELETE
request to the `/user/two-factor-authentication` endpoint. Remember, Fortify's
two factor authentication endpoints require password confirmation prior to
being called.
## Registration
To begin implementing our application's registration functionality, we need to
instruct Fortify how to return our "register" view. Remember, Fortify is a
headless authentication library. If you would like a frontend implementation
of Laravel's authentication features that are already completed for you, you
should use an [application starter kit](/docs/12.x/starter-kits).
All of Fortify's view rendering logic may be customized using the appropriate
methods available via the `Laravel\Fortify\Fortify` class. Typically, you
should call this method from the `boot` method of your
`App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::registerView(function () {
9 return view('auth.register');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::registerView(function () {
return view('auth.register');
});
// ...
}
Fortify will take care of defining the `/register` route that returns this
view. Your `register` template should include a form that makes a POST request
to the `/register` endpoint defined by Fortify.
The `/register` endpoint expects a string `name`, string email address /
username, `password`, and `password_confirmation` fields. The name of the
email / username field should match the `username` configuration value defined
within your application's `fortify` configuration file.
If the registration attempt is successful, Fortify will redirect the user to
the URI configured via the `home` configuration option within your
application's `fortify` configuration file. If the request was an XHR request,
a 201 HTTP response will be returned.
If the request was not successful, the user will be redirected back to the
registration screen and the validation errors will be available to you via the
shared `$errors` [Blade template variable](/docs/12.x/validation#quick-
displaying-the-validation-errors). Or, in the case of an XHR request, the
validation errors will be returned with a 422 HTTP response.
### Customizing Registration
The user validation and creation process may be customized by modifying the
`App\Actions\Fortify\CreateNewUser` action that was generated when you
installed Laravel Fortify.
## Password Reset
### Requesting a Password Reset Link
To begin implementing our application's password reset functionality, we need
to instruct Fortify how to return our "forgot password" view. Remember,
Fortify is a headless authentication library. If you would like a frontend
implementation of Laravel's authentication features that are already completed
for you, you should use an [application starter kit](/docs/12.x/starter-kits).
All of Fortify's view rendering logic may be customized using the appropriate
methods available via the `Laravel\Fortify\Fortify` class. Typically, you
should call this method from the `boot` method of your application's
`App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::requestPasswordResetLinkView(function () {
9 return view('auth.forgot-password');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::requestPasswordResetLinkView(function () {
return view('auth.forgot-password');
});
// ...
}
Fortify will take care of defining the `/forgot-password` endpoint that
returns this view. Your `forgot-password` template should include a form that
makes a POST request to the `/forgot-password` endpoint.
The `/forgot-password` endpoint expects a string `email` field. The name of
this field / database column should match the `email` configuration value
within your application's `fortify` configuration file.
#### Handling the Password Reset Link Request Response
If the password reset link request was successful, Fortify will redirect the
user back to the `/forgot-password` endpoint and send an email to the user
with a secure link they can use to reset their password. If the request was an
XHR request, a 200 HTTP response will be returned.
After being redirected back to the `/forgot-password` endpoint after a
successful request, the `status` session variable may be used to display the
status of the password reset link request attempt.
The value of the `$status` session variable will match one of the translation
strings defined within your application's `passwords` [language
file](/docs/12.x/localization). If you would like to customize this value and
have not published Laravel's language files, you may do so via the
`lang:publish` Artisan command:
1@if (session('status'))
2
3 {{ session('status') }}
4
5@endif
@if (session('status'))
{{ session('status') }}
@endif
If the request was not successful, the user will be redirected back to the
request password reset link screen and the validation errors will be available
to you via the shared `$errors` [Blade template
variable](/docs/12.x/validation#quick-displaying-the-validation-errors). Or,
in the case of an XHR request, the validation errors will be returned with a
422 HTTP response.
### Resetting the Password
To finish implementing our application's password reset functionality, we need
to instruct Fortify how to return our "reset password" view.
All of Fortify's view rendering logic may be customized using the appropriate
methods available via the `Laravel\Fortify\Fortify` class. Typically, you
should call this method from the `boot` method of your application's
`App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2use Illuminate\Http\Request;
3
4/**
5 * Bootstrap any application services.
6 */
7public function boot(): void
8{
9 Fortify::resetPasswordView(function (Request $request) {
10 return view('auth.reset-password', ['request' => $request]);
11 });
12
13 // ...
14}
use Laravel\Fortify\Fortify;
use Illuminate\Http\Request;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::resetPasswordView(function (Request $request) {
return view('auth.reset-password', ['request' => $request]);
});
// ...
}
Fortify will take care of defining the route to display this view. Your
`reset-password` template should include a form that makes a POST request to
`/reset-password`.
The `/reset-password` endpoint expects a string `email` field, a `password`
field, a `password_confirmation` field, and a hidden field named `token` that
contains the value of `request()->route('token')`. The name of the "email"
field / database column should match the `email` configuration value defined
within your application's `fortify` configuration file.
#### Handling the Password Reset Response
If the password reset request was successful, Fortify will redirect back to
the `/login` route so that the user can log in with their new password. In
addition, a `status` session variable will be set so that you may display the
successful status of the reset on your login screen:
1@if (session('status'))
2
3 {{ session('status') }}
4
5@endif
@if (session('status'))
{{ session('status') }}
@endif
If the request was an XHR request, a 200 HTTP response will be returned.
If the request was not successful, the user will be redirected back to the
reset password screen and the validation errors will be available to you via
the shared `$errors` [Blade template variable](/docs/12.x/validation#quick-
displaying-the-validation-errors). Or, in the case of an XHR request, the
validation errors will be returned with a 422 HTTP response.
### Customizing Password Resets
The password reset process may be customized by modifying the
`App\Actions\ResetUserPassword` action that was generated when you installed
Laravel Fortify.
## Email Verification
After registration, you may wish for users to verify their email address
before they continue accessing your application. To get started, ensure the
`emailVerification` feature is enabled in your `fortify` configuration file's
`features` array. Next, you should ensure that your `App\Models\User` class
implements the `Illuminate\Contracts\Auth\MustVerifyEmail` interface.
Once these two setup steps have been completed, newly registered users will
receive an email prompting them to verify their email address ownership.
However, we need to inform Fortify how to display the email verification
screen which informs the user that they need to go click the verification link
in the email.
All of Fortify's view's rendering logic may be customized using the
appropriate methods available via the `Laravel\Fortify\Fortify` class.
Typically, you should call this method from the `boot` method of your
application's `App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::verifyEmailView(function () {
9 return view('auth.verify-email');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::verifyEmailView(function () {
return view('auth.verify-email');
});
// ...
}
Fortify will take care of defining the route that displays this view when a
user is redirected to the `/email/verify` endpoint by Laravel's built-in
`verified` middleware.
Your `verify-email` template should include an informational message
instructing the user to click the email verification link that was sent to
their email address.
#### Resending Email Verification Links
If you wish, you may add a button to your application's `verify-email`
template that triggers a POST request to the `/email/verification-
notification` endpoint. When this endpoint receives a request, a new
verification email link will be emailed to the user, allowing the user to get
a new verification link if the previous one was accidentally deleted or lost.
If the request to resend the verification link email was successful, Fortify
will redirect the user back to the `/email/verify` endpoint with a `status`
session variable, allowing you to display an informational message to the user
informing them the operation was successful. If the request was an XHR
request, a 202 HTTP response will be returned:
1@if (session('status') == 'verification-link-sent')
2
3 A new email verification link has been emailed to you!
4
5@endif
@if (session('status') == 'verification-link-sent')
A new email verification link has been emailed to you!
@endif
### Protecting Routes
To specify that a route or group of routes requires that the user has verified
their email address, you should attach Laravel's built-in `verified`
middleware to the route. The `verified` middleware alias is automatically
registered by Laravel and serves as an alias for the
`Illuminate\Auth\Middleware\EnsureEmailIsVerified` middleware:
1Route::get('/dashboard', function () {
2 // ...
3})->middleware(['verified']);
Route::get('/dashboard', function () {
// ...
})->middleware(['verified']);
## Password Confirmation
While building your application, you may occasionally have actions that should
require the user to confirm their password before the action is performed.
Typically, these routes are protected by Laravel's built-in `password.confirm`
middleware.
To begin implementing password confirmation functionality, we need to instruct
Fortify how to return our application's "password confirmation" view.
Remember, Fortify is a headless authentication library. If you would like a
frontend implementation of Laravel's authentication features that are already
completed for you, you should use an [application starter
kit](/docs/12.x/starter-kits).
All of Fortify's view rendering logic may be customized using the appropriate
methods available via the `Laravel\Fortify\Fortify` class. Typically, you
should call this method from the `boot` method of your application's
`App\Providers\FortifyServiceProvider` class:
1use Laravel\Fortify\Fortify;
2
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Fortify::confirmPasswordView(function () {
9 return view('auth.confirm-password');
10 });
11
12 // ...
13}
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::confirmPasswordView(function () {
return view('auth.confirm-password');
});
// ...
}
Fortify will take care of defining the `/user/confirm-password` endpoint that
returns this view. Your `confirm-password` template should include a form that
makes a POST request to the `/user/confirm-password` endpoint. The
`/user/confirm-password` endpoint expects a `password` field that contains the
user's current password.
If the password matches the user's current password, Fortify will redirect the
user to the route they were attempting to access. If the request was an XHR
request, a 201 HTTP response will be returned.
If the request was not successful, the user will be redirected back to the
confirm password screen and the validation errors will be available to you via
the shared `$errors` Blade template variable. Or, in the case of an XHR
request, the validation errors will be returned with a 422 HTTP response.