Laravel 强化

Introduction

Laravel 强化 是 Laravel 的前端不可知认证后端实现。 Fortify 注册实现所有 Laravel 身份验证功能所需的路由和控制器,包括登录、注册、密码重置、电子邮件验证等。安装 Fortify 后,您可以运行route:list 用于查看 Fortify 已注册路由的 Artisan 命令。

由于 Fortify 不提供自己的用户界面,因此它应该与您自己的用户界面配对,后者向它注册的路由发出请求。我们将在本文档的其余部分讨论如何向这些路由发出请求。

Note
请记住,Fortify 是一个旨在让您抢先实施 Laravel 身份验证功能的软件包。您不需要使用它。 您始终可以按照 中可用的文档手动与 Laravel 的身份验证服务进行交互。authentication,重设密码, 和电子邮件验证 文档。

什么是强化?

如前所述,Laravel Fortify 是 Laravel 的前端不可知的身份验证后端实现。 Fortify 注册实现所有 Laravel 身份验证功能所需的路由和控制器,包括登录、注册、密码重置、电子邮件验证等。

您不需要使用 Fortify 来使用 Laravel 的身份验证功能。 您始终可以按照 中可用的文档手动与 Laravel 的身份验证服务进行交互。authentication,重设密码, 和电子邮件验证 文档。

如果你是 Laravel 的新手,你可能希望探索Laravel 微风 应用程序入门工具包,然后再尝试使用 Laravel Fortify。 Laravel Breeze 为您的应用程序提供了一个身份验证脚手架,其中包括一个使用顺风 CSS.与 Fortify 不同,Breeze 将其路由和控制器直接发布到您的应用程序中。这使您可以在允许 Laravel Fortify 为您实现这些功能之前学习并熟悉 Laravel 的身份验证功能。

Laravel Fortify 本质上采用了 Laravel Breeze 的路由和控制器,并将它们作为不包含用户界面的包提供。这使您仍然可以快速构建应用程序身份验证层的后端实现,而不必受制于任何特定的前端意见。

我什么时候应该使用 Fortify?

您可能想知道何时适合使用 Laravel Fortify。首先,如果你使用的是 Laravel 的一个应用入门套件,你不需要安装 Laravel Fortify,因为 Laravel 的所有应用程序入门工具包都已经提供了完整的身份验证实现。

如果您没有使用应用程序入门工具包并且您的应用程序需要身份验证功能,您有两个选择:手动实现应用程序的身份验证功能或使用 Laravel Fortify 提供这些功能的后端实现。

如果您选择安装 Fortify,您的用户界面将向本文档中详述的 Fortify 身份验证路由发出请求,以便对用户进行身份验证和注册。

如果您选择手动与 Laravel 的身份验证服务交互而不是使用 Fortify,您可以按照authentication,重设密码, 和电子邮件验证 文档。

Laravel Fortify 和 Laravel Sanctum

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

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

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

Installation

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

composer require laravel/fortify

接下来,使用发布 Fortify 的资源vendor:publish 命令:

php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

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

接下来,您应该迁移数据库:

php artisan migrate

Fortify 服务提供商

vendor:publish 上面讨论的命令还将发布App\Providers\FortifyServiceProvider 班级。您应该确保此类已在providers 你的应用程序的数组config/app.php 配置文件。

Fortify 服务提供者注册 Fortify 发布的操作,并指示 Fortify 在 Fortify 执行各自的任务时使用它们。

强化功能

fortify 配置文件包含一个features 配置数组。该数组定义 Fortify 默认公开哪些后端路由/功能。如果您没有将 Fortify 与Laravel 喷射流,我们建议您只启用以下功能,这是大多数 Laravel 应用程序提供的基本身份验证功能:

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

禁用视图

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

'views' => false,

禁用视图和密码重置

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

Authentication

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

所有身份验证视图的呈现逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级。 Fortify 将负责定义/login 返回此视图的路由:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::loginView(function () {
        return view('auth.login');
    });

    // ...
}

您的登录模板应包含一个表单,该表单向/login.这/login 端点需要一个字符串email /username 和一个password.电子邮件/用户名字段的名称应与username 内的价值config/fortify.php 配置文件。另外,一个布尔值remember 可以提供字段来指示用户想要使用 Laravel 提供的“记住我”功能。

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

如果请求不成功,用户将被重定向回登录屏幕,验证错误将通过共享提供给您$errors 刀片模板变量.或者,在 XHR 请求的情况下,验证错误将与 422 HTTP 响应一起返回。

自定义用户身份验证

Fortify 将根据提供的凭据和为您的应用程序配置的身份验证保护自动检索和验证用户。但是,有时您可能希望对登录凭据的身份验证方式和用户检索方式进行完全自定义。值得庆幸的是,Fortify 允许您使用Fortify::authenticateUsing 方法。

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

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;
        }
    });

    // ...
}

认证卫士

您可以在您的应用程序中自定义 Fortify 使用的身份验证保护fortify 配置文件。但是,您应该确保配置的守卫是Illuminate\Contracts\Auth\StatefulGuard.如果您尝试使用 Laravel Fortify 来验证 SPA,您应该使用 Laravel 的默认设置web 守卫结合Laravel 圣殿.

自定义身份验证管道

Laravel Fortify 通过可调用类的管道对登录请求进行身份验证。如果您愿意,您可以定义一个自定义的类管道,登录请求应该通过这些管道传输。每个班级都应该有一个__invoke 接收传入的方法Illuminate\Http\Request 例如,像middleware, A$next 为了将请求传递给管道中的下一个类而调用的变量。

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

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

use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Laravel\Fortify\Fortify;
use Illuminate\Http\Request;

Fortify::authenticateThrough(function (Request $request) {
    return array_filter([
            config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
            Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
            AttemptToAuthenticate::class,
            PrepareAuthenticatedSession::class,
    ]);
});

自定义重定向

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

如果您需要对此行为进行高级定制,您可以绑定LoginResponseLogoutResponse 合约进入 Laravel服务容器.通常,这应该在register 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Contracts\LogoutResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

/**
 * Register any application services.
 */
public function register(): void
{
    $this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
        public function toResponse(Request $request): RedirectResponse
        {
            return redirect('/');
        }
    });
}

双重身份验证

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

在开始之前,您应该首先确保您的应用程序的App\Models\User 模型使用Laravel\Fortify\TwoFactorAuthenticatable 特征:

<?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;
}

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

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

启用两因素身份验证

要开始启用双因素身份验证,您的应用程序应该向/user/two-factor-authentication Fortify 定义的端点。如果请求成功,用户将被重定向回之前的 URL 和status 会话变量将设置为two-factor-authentication-enabled.你可能会发现这一点status 模板中的会话变量以显示适当的成功消息。如果请求是 XHR 请求,200 将返回 HTTP 响应。

选择启用双因素身份验证后,用户仍必须通过提供有效的双因素身份验证代码来“确认”其双因素身份验证配置。因此,您的“成功”消息应指示用户仍然需要两因素身份验证确认:

@if (session('status') == 'two-factor-authentication-enabled')
    <div class="mb-4 font-medium text-sm">
        Please finish configuring two factor authentication below.
    </div>
@endif

接下来,您应该显示双因素身份验证 QR 码,供用户扫描到他们的身份验证器应用程序中。如果您使用 Blade 来呈现应用程序的前端,您可以使用以下方法检索 QR 码 SVGtwoFactorQrCodeSvg 用户实例上可用的方法:

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

如果您正在构建一个由 JavaScript 驱动的前端,您可以向/user/two-factor-qr-code 端点以检索用户的双因素身份验证二维码。此端点将返回一个 JSON 对象,其中包含svg 钥匙。

确认双因素身份验证

除了显示用户的双因素身份验证二维码之外,您还应该提供一个文本输入,用户可以在其中提供有效的身份验证代码以“确认”他们的双因素身份验证配置。这段代码应该通过 POST 请求提供给 Laravel 应用程序/user/confirmed-two-factor-authentication Fortify 定义的端点。

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

@if (session('status') == 'two-factor-authentication-confirmed')
    <div class="mb-4 font-medium text-sm">
        Two factor authentication confirmed and enabled successfully.
    </div>
@endif

如果通过 XHR 请求向双因素身份验证确认端点发出请求,则200 将返回 HTTP 响应。

显示恢复代码

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

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

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

要重新生成用户的恢复代码,您的应用程序应该向/user/two-factor-recovery-codes 端点。

使用双因素身份验证进行身份验证

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

要开始实施双因素身份验证功能,我们需要指示 Fortify 如何返回我们的双因素身份验证质询视图。 Fortify 的所有身份验证视图呈现逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::twoFactorChallengeView(function () {
        return view('auth.two-factor-challenge');
    });

    // ...
}

Fortify 将负责定义/two-factor-challenge 返回此视图的路由。你的two-factor-challenge 模板应包括一个向/two-factor-challenge 端点。这/two-factor-challenge 行动期望一个code 包含有效 TOTP 令牌或recovery_code 包含用户恢复代码之一的字段。

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

如果请求不成功,用户将被重定向回双因素挑战屏幕,验证错误将通过共享提供给您$errors 刀片模板变量.或者,在 XHR 请求的情况下,验证错误将通过 422 HTTP 响应返回。

禁用双因素身份验证

要禁用双因素身份验证,您的应用程序应该向/user/two-factor-authentication 端点。请记住,Fortify 的双因素身份验证端点需要确认密码 在被调用之前。

Registration

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

Fortify 的所有视图渲染逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::registerView(function () {
        return view('auth.register');
    });

    // ...
}

Fortify 将负责定义/register 返回此视图的路由。你的register 模板应包括一个向/register Fortify 定义的端点。

/register 端点需要一个字符串name, 字符串电子邮件地址/用户名,password, 和password_confirmation 领域。电子邮件/用户名字段的名称应与username 在您的应用程序中定义的配置值fortify 配置文件。

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

如果请求不成功,用户将被重定向回注册屏幕,验证错误将通过共享提供给您$errors 刀片模板变量.或者,在 XHR 请求的情况下,验证错误将通过 422 HTTP 响应返回。

自定义注册

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

重设密码

请求密码重置链接

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

Fortify 的所有视图渲染逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::requestPasswordResetLinkView(function () {
        return view('auth.forgot-password');
    });

    // ...
}

Fortify 将负责定义/forgot-password 返回此视图的端点。你的forgot-password 模板应包括一个向/forgot-password 端点。

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

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

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

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

的价值$status 会话变量将匹配应用程序中定义的翻译字符串之一passwords 语言文件.如果你想自定义这个值并且还没有发布 Laravel 的语言文件,你可以通过lang:publish 工匠命令:

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

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

重置密码

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

Fortify 的所有视图渲染逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

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 将负责定义显示此视图的路由。你的reset-password 模板应包含一个表单,该表单向/reset-password.

/reset-password 端点需要一个字符串email 领域,一个password 领域,一个password_confirmation 字段,以及一个名为token 包含的值request()->route('token'). “电子邮件”字段/数据库列的名称应与email 在您的应用程序中定义的配置值fortify 配置文件。

处理密码重置响应

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

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

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

如果请求不成功,用户将被重定向回重置密码屏幕,您将可以通过共享的验证错误$errors 刀片模板变量.或者,在 XHR 请求的情况下,验证错误将通过 422 HTTP 响应返回。

自定义密码重置

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

电子邮件验证

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

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

Fortify 的所有视图呈现逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::verifyEmailView(function () {
        return view('auth.verify-email');
    });

    // ...
}

当用户被重定向到/email/verify Laravel 内置的端点verified 中间件。

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

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

如果您愿意,您可以在应用程序的verify-email 触发 POST 请求的模板/email/verification-notification 端点。当此端点收到请求时,将通过电子邮件将新的验证电子邮件链接发送给用户,如果先前的验证链接被意外删除或丢失,则允许用户获取新的验证链接。

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

@if (session('status') == 'verification-link-sent')
    <div class="mb-4 font-medium text-sm text-green-600">
        A new email verification link has been emailed to you!
    </div>
@endif

保护路线

要指定一个路由或一组路由需要用户验证他们的电子邮件地址,你应该附加 Laravel 的内置verified 路由的中间件。该中间件已在您的应用程序的App\Http\Kernel 班级:

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

确认密码

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

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

Fortify 的所有视图渲染逻辑都可以使用通过Laravel\Fortify\Fortify 班级。通常,您应该从boot 你的应用程序的方法App\Providers\FortifyServiceProvider 班级:

use Laravel\Fortify\Fortify;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Fortify::confirmPasswordView(function () {
        return view('auth.confirm-password');
    });

    // ...
}

Fortify 将负责定义/user/confirm-password 返回此视图的端点。你的confirm-password 模板应包括一个向/user/confirm-password 端点。这/user/confirm-password 端点期望一个password 包含用户当前密码的字段。

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

如果请求不成功,用户将被重定向回确认密码屏幕,验证错误将通过共享提供给您$errors 刀片模板变量。或者,在 XHR 请求的情况下,验证错误将通过 422 HTTP 响应返回。

豫ICP备18041297号-2