Skip to content
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

Laravel Fortify ​

简介 ​

Laravel Fortify 是一个 Laravel 的后端认证实现,它不依赖于前端。Fortify 注册了实现 Laravel 所有认证功能所需的路由和控制器,包括登录、注册、密码重置、邮箱验证等等。安装 Fortify 后,你可以运行 route:list Artisan 命令来查看 Fortify 已注册的路由。

由于 Fortify 不提供自己的用户界面,它旨在与你自己的用户界面配合使用,该界面会向它注册的路由发起请求。我们将在本文档的其余部分详细讨论如何向这些路由发起请求。

注意

请记住,Fortify 是一个旨在让你快速实现 Laravel 认证功能的包。你并非必须使用它。 你始终可以按照认证、密码重置和邮箱验证文档中提供的指南,手动与 Laravel 的认证服务进行交互。

什么是 Fortify? ​

如前所述,Laravel Fortify 是一个 Laravel 的后端认证实现,它不依赖于前端。Fortify 注册了实现 Laravel 所有认证功能所需的路由和控制器,包括登录、注册、密码重置、邮箱验证等等。

你并非必须使用 Fortify 才能使用 Laravel 的认证功能。 你始终可以按照认证、密码重置和邮箱验证文档中提供的指南,手动与 Laravel 的认证服务进行交互。

如果你刚接触 Laravel,你可能希望探索我们的应用启动套件。Laravel 的应用启动套件内部使用 Fortify,为你的应用提供包含使用 Tailwind CSS 构建的用户界面的认证脚手架。这可以让你学习和熟悉 Laravel 的认证功能。

Laravel Fortify 本质上采用了我们应用启动套件的路由和控制器,并将它们作为一个不包含用户界面的包提供。这样,你仍然可以快速搭建应用认证层的后端实现,而不受任何特定前端选择的束缚。

何时应该使用 Fortify? ​

你可能想知道什么时候适合使用 Laravel Fortify。首先,如果你正在使用 Laravel 的某个应用启动套件,则无需安装 Laravel Fortify,因为所有 Laravel 应用启动套件都使用了 Fortify,并且已经提供了完整的认证实现。

如果你没有使用应用启动套件,并且你的应用需要认证功能,那么你有两个选择:手动实现应用的认证功能,或者使用 Laravel Fortify 来提供这些功能的后端实现。

如果你选择安装 Fortify,你的用户界面将向本文档中详细介绍的 Fortify 认证路由发起请求,以认证和注册用户。

如果你选择手动与 Laravel 的认证服务交互而不使用 Fortify,可以按照认证、密码重置和邮箱验证文档中提供的指南进行操作。

Laravel Fortify 和 Laravel Sanctum ​

一些开发者对 Laravel Sanctum 和 Laravel Fortify 之间的区别感到困惑。因为这两个包解决了两个不同但相关的问题,Laravel Fortify 和 Laravel Sanctum 并不是互斥或竞争的包。

Laravel Sanctum 只关心管理 API 令牌以及使用会话 Cookie 或令牌对现有用户进行认证。Sanctum 不提供任何处理用户注册、密码重置等的路由。

如果你正在为提供 API 或作为单页应用后端的应用手动构建认证层,你完全有可能同时使用 Laravel Fortify(用于用户注册、密码重置等)和 Laravel Sanctum(用于 API 令牌管理、会话认证)。

安装 ​

首先,使用 Composer 包管理器安装 Fortify:

shell
composer require laravel/fortify

接下来,使用 fortify:install Artisan 命令发布 Fortify 的资源:

shell
php artisan fortify:install

此命令会将 Fortify 的操作发布到你的 app/Actions 目录(如果不存在则会创建)。此外,FortifyServiceProvider、配置文件和所有必要的数据库迁移都会被发布。

然后,你应该运行数据库迁移:

shell
php artisan migrate

Fortify 功能 ​

fortify 配置文件包含一个 features 配置数组。该数组定义了 Fortify 默认会暴露哪些后端路由/功能。我们建议你仅启用以下功能,这些是大多数 Laravel 应用程序提供的基本认证功能:

php
'features' => [
    Features::registration(),
    Features::resetPasswords(),
    Features::emailVerification(),
],

禁用视图 ​

默认情况下,Fortify 定义了旨在返回视图的路由,例如登录屏幕或注册屏幕。但是,如果你正在构建一个由 JavaScript 驱动的单页应用,你可能不需要这些路由。因此,你可以通过在应用程序的 config/fortify.php 配置文件中将 views 配置值设置为 false 来完全禁用这些路由:

php
'views' => false,

禁用视图和密码重置 ​

如果你选择禁用 Fortify 的视图,并且将为你的应用程序实现密码重置功能,你仍然应该定义一个名为 password.reset 的路由,该路由负责显示应用程序的“重置密码”视图。这是必要的,因为 Laravel 的 Illuminate\Auth\Notifications\ResetPassword 通知将通过名为 password.reset 的路由来生成密码重置 URL。

认证 ​

首先,我们需要指导 Fortify 如何返回我们的“登录”视图。请记住,Fortify 是一个无头认证库。如果你想要一个已经为你完成的 Laravel 认证功能的前端实现,你应该使用应用启动套件。

所有认证视图的渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法。Fortify 将负责定义返回此视图的 /login 路由:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::loginView(function () {
        return view('auth.login');
    });

    // ...
}

你的登录模板应包含一个向 /login 发起 POST 请求的表单。/login 端点需要一个字符串 email/username 和一个 password。邮箱/用户名字段的名称应与 config/fortify.php 配置文件中的 username 值匹配。此外,可以提供一个布尔值 remember 字段,以指示用户想要使用 Laravel 提供的“记住我”功能。

如果登录尝试成功,Fortify 会将你重定向到应用程序 fortify 配置文件中通过 home 配置选项配置的 URI。如果登录请求是 XHR 请求,将返回 200 HTTP 响应。

如果请求不成功,用户将被重定向回登录屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。

自定义用户认证 ​

Fortify 将根据提供的凭据和为你的应用程序配置的认证守卫自动检索和认证用户。但是,有时你可能希望完全自定义登录凭据的认证方式和用户的检索方式。幸运的是,Fortify 允许你使用 Fortify::authenticateUsing 方法轻松实现这一点。

此方法接受一个接收传入 HTTP 请求的闭包。该闭包负责验证请求中包含的登录凭据并返回关联的用户实例。如果凭据无效或找不到用户,闭包应返回 null 或 false。通常,此方法应在你的 FortifyServiceProvider 的 boot 方法中调用:

php
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
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;
        }
    });

    // ...
}

认证守卫 ​

你可以在应用程序的 fortify 配置文件中自定义 Fortify 使用的认证守卫。但是,应确保配置的守卫是 Illuminate\Contracts\Auth\StatefulGuard 的实现。如果你尝试使用 Laravel Fortify 来认证单页应用,你应该将 Laravel 默认的 web 守卫与 Laravel Sanctum 结合使用。

自定义认证管道 ​

Laravel Fortify 通过一系列可调用类的管道来认证登录请求。如果你愿意,你可以定义一个自定义的类管道,登录请求将通过这些类进行处理。每个类应该有一个 __invoke 方法,该方法接收传入的 Illuminate\Http\Request 实例,并且像中间件一样,接收一个 $next 变量,该变量被调用以将请求传递给管道中的下一个类。

要定义你的自定义管道,你可以使用 Fortify::authenticateThrough 方法。此方法接受一个闭包,该闭包应返回用于传递登录请求的类数组。通常,此方法应在你的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用。

下面的示例包含默认管道定义,在进行自己的修改时,你可以将其用作起点:

php
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,
    ]);
});

认证频率限制 ​

默认情况下,Fortify 会使用 EnsureLoginIsNotThrottled 中间件来限制认证尝试频率。该中间件会限制特定用户名和 IP 地址组合的尝试次数。

某些应用程序可能需要不同的认证尝试频率限制方法,例如仅按 IP 地址限制。因此,Fortify 允许你通过 fortify.limiters.login 配置选项指定你自己的频率限制器。当然,此配置选项位于你应用程序的 config/fortify.php 配置文件中。

注意

结合使用频率限制、双因素认证和外部 Web 应用防火墙(WAF),将为你的合法应用程序用户提供最强大的防御。

自定义重定向 ​

如果登录尝试成功,Fortify 会将你重定向到应用程序 fortify 配置文件中通过 home 配置选项配置的 URI。如果登录请求是 XHR 请求,将返回 200 HTTP 响应。用户注销应用程序后,将被重定向到 / URI。

如果你需要对此行为进行高级自定义,可以将 LoginResponse 和 LogoutResponse 契约的实现绑定到 Laravel 服务容器中。通常,这应该在应用程序的 App\Providers\FortifyServiceProvider 类的 register 方法中完成:

php
use Laravel\Fortify\Contracts\LogoutResponse;

/**
 * 注册任何应用程序服务。
 */
public function register(): void
{
    $this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
        public function toResponse($request)
        {
            return redirect('/');
        }
    });
}

双因素认证 ​

当启用了 Fortify 的双因素认证功能时,用户在认证过程中需要输入一个六位数字令牌。此令牌使用基于时间的一次性密码(TOTP)生成,可以从任何兼容 TOTP 的移动认证应用程序(如 Google Authenticator)获取。

开始之前,应首先确保你的应用程序的 App\Models\User 模型使用了 Laravel\Fortify\TwoFactorAuthenticatable trait:

php
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use Notifiable, TwoFactorAuthenticatable;
}

接下来,你应该在应用程序中构建一个屏幕,用户可以在其中管理他们的双因素认证设置。此屏幕应允许用户启用和禁用双因素认证,以及重新生成他们的双因素认证恢复码。

默认情况下,fortify 配置文件的 features 数组指示 Fortify 的双因素认证设置在修改前需要密码确认。因此,你的应用程序在继续之前应先实现 Fortify 的密码确认功能。

启用双因素认证 ​

要开始启用双因素认证,你的应用程序应向 Fortify 定义的 /user/two-factor-authentication 端点发起 POST 请求。如果请求成功,用户将被重定向回之前的 URL,并且 status 会话变量将被设置为 two-factor-authentication-enabled。你可以在模板中检测此 status 会话变量以显示相应的成功消息。如果请求是 XHR 请求,将返回 200 HTTP 响应。

选择启用双因素认证后,用户仍然必须通过提供一个有效的双因素认证代码来“确认”他们的双因素认证配置。因此,你的“成功”消息应告知用户仍然需要确认双因素认证:

html
@if (session('status') == 'two-factor-authentication-enabled')
    <div class="mb-4 font-medium text-sm">
        请在下方完成双因素认证配置。
    </div>
@endif

接下来,你应该显示双因素认证二维码,供用户扫描到他们的认证器应用程序中。如果你使用 Blade 渲染应用程序的前端,你可以使用用户实例上可用的 twoFactorQrCodeSvg 方法检索二维码 SVG:

php
$request->user()->twoFactorQrCodeSvg();

如果你正在构建一个由 JavaScript 驱动的前端,你可以向 /user/two-factor-qr-code 端点发起 XHR GET 请求,以检索用户的双因素认证二维码。此端点将返回一个包含 svg 键的 JSON 对象。

确认双因素认证 ​

除了显示用户的双因素认证二维码,你还应该提供一个文本输入框,用户可以在此提供有效的认证代码以“确认”他们的双因素认证配置。此代码应通过向 Fortify 定义的 /user/confirmed-two-factor-authentication 端点发起 POST 请求提供给 Laravel 应用程序。

如果请求成功,用户将被重定向回之前的 URL,并且 status 会话变量将被设置为 two-factor-authentication-confirmed:

html
@if (session('status') == 'two-factor-authentication-confirmed')
    <div class="mb-4 font-medium text-sm">
        双因素认证已确认并成功启用。
    </div>
@endif

如果对双因素认证确认端点的请求是通过 XHR 请求发起的,将返回一个 200 HTTP 响应。

显示恢复码 ​

你还应该显示用户的双因素恢复码。这些恢复码允许用户在无法访问移动设备时进行认证。如果你使用 Blade 渲染应用程序的前端,你可以通过已认证的用户实例访问恢复码:

php
(array) $request->user()->recoveryCodes();

如果你正在构建一个由 JavaScript 驱动的前端,你可以向 /user/two-factor-recovery-codes 端点发起 XHR GET 请求。此端点将返回一个包含用户恢复码的 JSON 数组。

要重新生成用户的恢复码,你的应用程序应向 /user/two-factor-recovery-codes 端点发起 POST 请求。

使用双因素认证进行认证 ​

在认证过程中,Fortify 会自动将用户重定向到应用程序的双因素认证挑战屏幕。但是,如果你的应用程序正在发起 XHR 登录请求,成功认证尝试后返回的 JSON 响应将包含一个具有 two_factor 布尔属性的 JSON 对象。你应该检查此值以确定是否应重定向到应用程序的双因素认证挑战屏幕。

要开始实现双因素认证功能,我们需要指导 Fortify 如何返回我们的双因素认证挑战视图。所有 Fortify 的认证视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::twoFactorChallengeView(function () {
        return view('auth.two-factor-challenge');
    });

    // ...
}

Fortify 将负责定义返回此视图的 /two-factor-challenge 路由。你的 two-factor-challenge 模板应包含一个向 /two-factor-challenge 端点发起 POST 请求的表单。/two-factor-challenge 操作期望一个包含有效 TOTP 令牌的 code 字段,或一个包含用户某个恢复码的 recovery_code 字段。

如果登录尝试成功,Fortify 会将用户重定向到应用程序 fortify 配置文件中通过 home 配置选项配置的 URI。如果登录请求是 XHR 请求,将返回 204 HTTP 响应。

如果请求不成功,用户将被重定向回双因素挑战屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。

禁用双因素认证 ​

要禁用双因素认证,你的应用程序应向 /user/two-factor-authentication 端点发起 DELETE 请求。请记住,Fortify 的双因素认证端点在调用前需要密码确认。

通行密钥 ​

Fortify 支持使用 WebAuthn 进行通行密钥认证。通行密钥允许用户通过平台认证器(如 Face ID、Touch ID、Windows Hello 或硬件安全密钥)进行无密码认证。

启用通行密钥 ​

开始前,请确保在应用的 fortify 配置文件中启用了 passkeys 特性:

php
use Laravel\Fortify\Features;

'features' => [
    // ...
    Features::passkeys([
        'confirmPassword' => true,
    ]),
],

confirmPassword 选项决定在注册或删除通行密钥之前,Fortify 是否需要密码确认。

接下来,确保应用的 App\Models\User 模型实现了 Laravel\Fortify\Contracts\PasskeyUser 并使用了 Laravel\Fortify\PasskeyAuthenticatable trait:

php
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\Contracts\PasskeyUser;
use Laravel\Fortify\PasskeyAuthenticatable;

class User extends Authenticatable implements PasskeyUser
{
    use Notifiable, PasskeyAuthenticatable;
}

可以通过应用 config/fortify.php 文件中的 passkeys 配置数组自定义 Fortify 的通行密钥配置选项:

php
'passkeys' => [
    'relying_party_id' => parse_url(config('app.url'), PHP_URL_HOST),
    'allowed_origins' => [config('app.url')],
    'user_handle_secret' => config('app.key'),
    'timeout' => 60000,
],

注意

Fortify 封装了 laravel/passkeys Composer 包并为你完成配置。如果你使用 Fortify 的通行密钥功能,应通过应用的 config/fortify.php 文件进行配置。无需发布 laravel/passkeys 配置文件,其中的任何值都会被 Fortify 覆盖。

relying_party_id 应与你应用的域名匹配。allowed_origins 数组列出了允许完成通行密钥注册和认证的浏览器来源。user_handle_secret 用于派生不透明的用户标识符,确保同一用户在多次通行密钥注册中能被识别。timeout 选项控制通行密钥注册和认证操作可保持活跃的时长。

Fortify 会为通行密钥的登录、确认和注册路由应用一个专门的通行密钥速率限制器。如需自定义,可以使用 fortify.limiters.passkeys 配置选项及对应的 RateLimiter::for(...) 定义。

JavaScript 客户端 ​

如果你在构建自定义前端,包括包含浏览器端脚本的 Blade 应用,可以使用官方的 @laravel/passkeys 包。该包处理浏览器的 WebAuthn 仪式并向 Fortify 的通行密钥端点发送请求。

通过 npm 安装此包:

shell
npm install @laravel/passkeys

然后,就可以在前端发起通行密钥注册和验证:

js
import { Passkeys } from "@laravel/passkeys";

await Passkeys.register({ name: "MacBook Pro" });
await Passkeys.verify();

如果你的应用使用了自定义的通行密钥端点 URI,可以按调用覆写路由:

js
await Passkeys.verify({
    routes: {
        options: "/passkeys/confirm/options",
        submit: "/passkeys/confirm",
    },
});

await Passkeys.register({
    name: "MacBook Pro",
    routes: {
        options: "/user/passkeys/options",
        submit: "/user/passkeys",
    },
});

该包还通过 @laravel/passkeys/react、@laravel/passkeys/vue 和 @laravel/passkeys/svelte 提供了 React、Vue 及 Svelte 辅助工具。

使用通行密钥进行认证 ​

要使用通行密钥对用户进行认证,应用首先应向 /passkeys/login/options 端点发起 GET 请求。该端点返回 WebAuthn 挑战选项,你的前端应将这些选项传递给 navigator.credentials.get(...)。

浏览器返回凭证后,应用需向 /passkeys/login 发起 POST 请求,并携带凭证载荷。你还可以包含一个布尔类型的 remember 字段。

如果请求成功,Fortify 会将用户登录到配置的守卫(guard)中,并返回以下之一:

  • 针对标准请求,重定向响应到你预期的目标地址。
  • 针对 XHR 请求,包含 JSON 载荷且带有 redirect 键的 200 HTTP 响应。

使用通行密钥确认密码 ​

对于已认证的会话,Fortify 提供了通行密钥确认端点,以满足 Laravel 对当前会话的密码确认要求。

要使用通行密钥进行确认,应用首先应向 /passkeys/confirm/options 发起 GET 请求。该端点返回 WebAuthn 挑战选项,你的前端应将这些选项传递给 navigator.credentials.get(...)。

浏览器返回凭证后,应用需向 /passkeys/confirm 发起 POST 请求,并携带凭证载荷。

如果请求成功,Fortify 会将当前会话标记为已确认密码状态,并返回以下之一:

  • 针对标准请求,重定向响应到你预期的目标地址。
  • 针对 XHR 请求,包含 JSON 载荷且带有 redirect 键的 200 HTTP 响应。

注册通行密钥 ​

要为已认证的用户注册通行密钥,应用首先应向 /user/passkeys/options 发起 GET 请求。该端点返回 WebAuthn 创建选项,你的前端应将这些选项传递给 navigator.credentials.create(...)。

浏览器返回凭证后,应用需向 /user/passkeys 发起 POST 请求,并携带 name 字段和 credential 字段,其中 credential 字段应包含 navigator.credentials.create(...) 返回的序列化 PublicKeyCredential 对象。

如果请求成功,Fortify 将返回以下之一:

  • 针对标准请求,重定向回上一页,并在会话中带有 passkey-registered 状态。
  • 带有 JSON 载荷的 200 HTTP 响应,其中包含 status 键,以及新注册通行密钥的 id 和 name。

删除通行密钥 ​

要删除通行密钥,应用需向 /user/passkeys/{passkey} 发起 DELETE 请求。

如果请求成功,Fortify 将返回以下之一:

  • 针对标准请求,重定向回上一页,并在会话中带有 passkey-deleted 状态。
  • 针对 XHR 请求,包含 JSON 载荷且带有 status 键的 200 HTTP 响应。

注册 ​

要开始实现我们应用程序的注册功能,我们需要指导 Fortify 如何返回我们的“注册”视图。请记住,Fortify 是一个无头认证库。如果你想要一个已经为你完成的 Laravel 认证功能的前端实现,你应该使用应用启动套件。

所有 Fortify 的视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在你的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::registerView(function () {
        return view('auth.register');
    });

    // ...
}

Fortify 将负责定义返回此视图的 /register 路由。你的 register 模板应包含一个向 Fortify 定义的 /register 端点发起 POST 请求的表单。

/register 端点需要一个字符串 name、字符串 email 地址/用户名、password 和 password_confirmation 字段。邮箱/用户名字段的名称应与应用程序 fortify 配置文件中定义的 username 配置值匹配。

如果注册尝试成功,Fortify 会将用户重定向到应用程序 fortify 配置文件中通过 home 配置选项配置的 URI。如果请求是 XHR 请求,将返回 201 HTTP 响应。

如果请求不成功,用户将被重定向回注册屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。

自定义注册 ​

用户验证和创建过程可以通过修改安装 Laravel Fortify 时生成的 App\Actions\Fortify\CreateNewUser 操作来自定义。

密码重置 ​

请求密码重置链接 ​

要开始实现我们应用程序的密码重置功能,我们需要指导 Fortify 如何返回我们的“忘记密码”视图。请记住,Fortify 是一个无头认证库。如果你想要一个已经为你完成的 Laravel 认证功能的前端实现,你应该使用应用启动套件。

所有 Fortify 的视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::requestPasswordResetLinkView(function () {
        return view('auth.forgot-password');
    });

    // ...
}

Fortify 将负责定义返回此视图的 /forgot-password 端点。你的 forgot-password 模板应包含一个向 /forgot-password 端点发起 POST 请求的表单。

/forgot-password 端点需要一个字符串 email 字段。此字段/数据库列的名称应与应用程序 fortify 配置文件中的 email 配置值匹配。

处理密码重置链接请求的响应 ​

如果密码重置链接请求成功,Fortify 会将用户重定向回 /forgot-password 端点,并向用户发送一封包含安全链接的电子邮件,他们可以使用该链接重置密码。如果请求是 XHR 请求,将返回 200 HTTP 响应。

成功请求后重定向回 /forgot-password 端点时,可以使用 status 会话变量来显示密码重置链接请求尝试的状态。

$status 会话变量的值将匹配应用程序的 passwords 语言文件中定义的某个翻译字符串。如果你想自定义此值并且尚未发布 Laravel 的语言文件,可以通过 lang:publish Artisan 命令进行发布:

html
@if (session('status'))
    <div class="mb-4 font-medium text-sm text-green-600">
        {{ session('status') }}
    </div>
@endif

如果请求不成功,用户将被重定向回请求密码重置链接屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。

重置密码 ​

要完成我们应用程序的密码重置功能实现,我们需要指导 Fortify 如何返回我们的“重置密码”视图。

所有 Fortify 的视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;
use Illuminate\Http\Request;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::resetPasswordView(function (Request $request) {
        return view('auth.reset-password', ['request' => $request]);
    });

    // ...
}

Fortify 将负责定义显示此视图的路由。你的 reset-password 模板应包含一个向 /reset-password 发起 POST 请求的表单。

/reset-password 端点需要一个字符串 email 字段、一个 password 字段、一个 password_confirmation 字段,以及一个名为 token 的隐藏字段,其值为 request()->route('token')。“email”字段/数据库列的名称应与应用程序 fortify 配置文件中定义的 email 配置值匹配。

处理密码重置响应 ​

如果密码重置请求成功,Fortify 将重定向回 /login 路由,以便用户可以使用新密码登录。此外,还会设置一个 status 会话变量,以便你可以在登录屏幕上显示重置成功的状态:

blade
@if (session('status'))
    <div class="mb-4 font-medium text-sm text-green-600">
        {{ session('status') }}
    </div>
@endif

如果请求是 XHR 请求,将返回 200 HTTP 响应。

如果请求不成功,用户将被重定向回重置密码屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。

自定义密码重置 ​

密码重置过程可以通过修改安装 Laravel Fortify 时生成的 App\Actions\Fortify\ResetUserPassword 操作来自定义。

邮箱验证 ​

注册后,你可能希望用户在继续访问你的应用程序之前验证他们的电子邮件地址。首先,确保在 fortify 配置文件的 features 数组中启用了 emailVerification 功能。接下来,应确保你的 App\Models\User 类实现了 Illuminate\Contracts\Auth\MustVerifyEmail 接口。

完成这两个设置步骤后,新注册的用户将收到一封提示他们验证电子邮件地址所有权的电子邮件。但是,我们需要告知 Fortify 如何显示电子邮件验证屏幕,该屏幕告知用户需要点击电子邮件中的验证链接。

所有 Fortify 视图的渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::verifyEmailView(function () {
        return view('auth.verify-email');
    });

    // ...
}

当用户被 Laravel 内置的 verified 中间件重定向到 /email/verify 端点时,Fortify 将负责定义显示此视图的路由。

你的 verify-email 模板应包含一条信息性消息,指示用户点击发送到其电子邮件地址的电子邮件验证链接。

重新发送电子邮件验证链接 ​

如果你愿意,可以在应用程序的 verify-email 模板中添加一个按钮,该按钮会向 /email/verification-notification 端点触发 POST 请求。当此端点收到请求时,将向用户发送新的验证电子邮件链接,如果之前的链接被意外删除或丢失,用户可以获得新的验证链接。

如果重新发送验证链接电子邮件的请求成功,Fortify 会将用户重定向回 /email/verify 端点,并附带一个 status 会话变量,允许你显示一条信息性消息,告知用户操作成功。如果请求是 XHR 请求,将返回 202 HTTP 响应:

blade
@if (session('status') == 'verification-link-sent')
    <div class="mb-4 font-medium text-sm text-green-600">
        一个新的电子邮件验证链接已发送到你的邮箱!
    </div>
@endif

保护路由 ​

要指定一个路由或一组路由需要用户已验证其电子邮件地址,你应该将 Laravel 内置的 verified 中间件附加到该路由。verified 中间件别名由 Laravel 自动注册,是 Illuminate\Auth\Middleware\EnsureEmailIsVerified 中间件的别名:

php
Route::get('/dashboard', function () {
    // ...
})->middleware(['verified']);

密码确认 ​

在构建应用程序时,有时可能会有一些操作需要用户在执行前确认其密码。通常,这些路由由 Laravel 内置的 password.confirm 中间件保护。

要开始实现密码确认功能,我们需要指导 Fortify 如何返回我们的应用程序的“密码确认”视图。请记住,Fortify 是一个无头认证库。如果你想要一个已经为你完成的 Laravel 认证功能的前端实现,你应该使用应用启动套件。

所有 Fortify 的视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类提供的相应方法进行自定义。通常,你应该在应用程序的 App\Providers\FortifyServiceProvider 类的 boot 方法中调用此方法:

php
use Laravel\Fortify\Fortify;

/**
 * 引导任何应用程序服务。
 */
public function boot(): void
{
    Fortify::confirmPasswordView(function () {
        return view('auth.confirm-password');
    });

    // ...
}

Fortify 将负责定义返回此视图的 /user/confirm-password 端点。你的 confirm-password 模板应包含一个向 /user/confirm-password 端点发起 POST 请求的表单。/user/confirm-password 端点需要一个包含用户当前密码的 password 字段。

如果密码与用户的当前密码匹配,Fortify 会将用户重定向到他们试图访问的路由。如果请求是 XHR 请求,将返回 201 HTTP 响应。

如果请求不成功,用户将被重定向回密码确认屏幕,并且验证错误将通过共享的 $errors Blade 模板变量提供给你。或者,对于 XHR 请求,验证错误将随 422 HTTP 响应返回。