Fortify 授权生成器
Laravel Fortify#
介绍#
Lravel Fortify 是一个与前端无关的身份认证后端实现。Fortify 注册了所有实现 Laravel 身份验证功能所需的路由和控制器,包括登录,注册,重置密码,邮件认证等。安装 Fortify 之后,你可以运行 Artisan 命令 route:list
来查看 Fortify 已注册的路由。
由于 Fortify 不提供其自己的用户界面,因此应与你自己的用户界面配对,该用户界面向其注册的路由发出请求。在本文档的其余部分中,我们将进一步讨论如何向这些路由发出请求。
技巧:请记住,Fortify 是一个软件包,旨在使你能够快速开始实施 Laravel 的身份验证功能。你不必非要使用它不可。 你始终可以按照以下说明中提供的文档,自由地与 Laravel 的身份认证服务进行交互,用户认证, 重置密码 和 邮箱认证 文档。
Fortify 是什么?#
如上所述,Laravel Fortify 是一个与前端无关的身份认证后端实现,Fortify 注册了所有实现 Laravel 身份验证功能所需的路由和控制器,包括登录,注册,重置密码,邮件认证等。
你不必使用 Fortify,也可以使用 Laravel 的身份认证功能。 你始终可以按照以下说明中提供的文档,自由地与 Laravel 的身份认证服务进行交互,用户认证,重置密码 和 邮箱认证 文档。
如果你是一名新手,在使用 Laravel Fortify 之前不妨尝试使用 Laravel Breeze 应用入门套件。Laravel Breeze 为你的应用提供身份认证支架,其中包括使用 Tailwind CSS。与 Fortify 不同,Breeze 将其路由和控制器直接发布到你的应用程序中。这使你可以学习并熟悉 Laravel 的身份认证功能,然后再允许 Laravel Fortify 为您实现这些功能。
Laravel Fortify 本质上是采用了 Laravel Breeze 的路由和控制器,且提供了不包含用户界面的扩展。这样,你可以快速搭建应用程序身份认证层的后端实现,而不必依赖于任何特定的前端意见。
何时使用 Fortify?#
你可能想知道何时使用 Laravel Fortify。 首先, 如果你正在使用 Laravel 的 应用入门套件, 你不需要安装 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:
composer require laravel/fortify
下一步,使用 vendor:publish
命令来发布 Fortify 的资源:
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
该命令会将 Fortify 的行为类发布到您的 app/Actions
目录,如果该目录不存在,则会创建该目录。此外,还将发布 Fortify 的配置和迁移文件。
下一步,你应该迁移数据库:
php artisan migrate
Fortify 服务提供商#
上面讨论的 vendor:publish
命令还将发布 App\Providers\FortifyServiceProvider
类。你应该确保该类已在应用程序的 config/app.php
配置文件的 providers
数组中注册。
Fortify 服务提供商注册了 Fortify 所发布的行为类,并指导 Fortify 在执行各自的任务时使用它们。
Fortify 包含的功能#
fortify
配置文件包含一个 features
配置数组。 该数组默路定义了 Fortify 的路由和功能。如果你不打算将 Fortify 与 Laravel Jetstream 配合使用,我们建议你仅启用以下功能,这是大多数 Laravel 应用提供的基本身份认证功能:
'features' => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
],
禁用视图#
默认情况下,Fortify 定义用于返回视图的路由,例如登录或注册。但是,如果要构建 JavaScript 驱动的单页应用,那么可能不需要这些路由。因此,你可以通过将 config/fortify.php
配置文件中的 views
配置值设为 false
来禁用这些路由:
'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
路由:
use Laravel\Fortify\Fortify;
/**
* 引导任何应用服务。
*
* @return void
*/
public function boot()
{
Fortify::loginView(fn () => view('auth.login'));
// ...
}
你的登录模板应包括一个向 /login
发出 POST 请求的表单。/login
表单需要一个电子邮件地址、用户名和一个 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
方法中调用:
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Fortify\Fortify;
/**
* 引导应用服务
*
* @return void
*/
public function boot()
{
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 Sanctum 结合使用。
双重认证#
当 Fortify 的双重因素身份验证功能启用时,用户需要在身份验证过程中输入一个六位数的数字令牌。 此令牌是使用基于时间的一次性密码 (TOTP) 生成的,该密码可从任何与 TOTP 兼容的移动身份验证应用程序(例如 Google Authenticator)中检索。
在开始之前,你应该首先确保你的应用程序的 App\Models\User
模型使用 Laravel\Fortify\TwoFactorAuthenticatable
trait:
<?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
session 变量将设置为 two-factor-authentication-enabled
。 您可以在模板中检测这个 status
session 变量以显示适当的成功消息。 如果请求是 XHR 请求,将返回 200
HTTP 响应:
@if (session('status') == 'two-factor-authentication-enabled')
<div class="mb-4 font-medium text-sm text-green-600">
Two factor authentication has been enabled.
</div>
@endif
接下来,您应该显示双重身份验证二维码,供用户扫描到他们的身份验证器应用程序中。 如果您使用 Blade 呈现应用程序的前端,则可以使用用户实例上可用的twoFactorQrCodeSvg
方法检索二维码 SVG:
$request->user()->twoFactorQrCodeSvg();
如果您正在构建由 JavaScript 驱动的前端,您可以向 /user/two-factor-qr-code
发出 XHR GET 请求以检索用户的双重身份验证二维码。 将返回一个包含 svg
键的 JSON 对象。
显示恢复码#
您还应该显示用户的双因子恢复码。 这些恢复码允许用户在无法访问其移动设备时进行身份验证。 如果您使用 Blade 呈现应用程序的前端,您可以通过经过身份验证的用户实例访问恢复码:
(array) $request->user()->two_factor_recovery_codes
如果你正在构建一个 JavaScript 驱动的前端,你可以向 /user/two-factor-recovery-codes
发出 XHR GET 请求。 将返回一个包含用户恢复码的 JSON 数组。
要重新生成用户的恢复码,您的应用程序应该向 /user/two-factor-recovery-codes
发出 POST 请求。
使用双重验证#
在身份验证过程中,Fortify 会自动将用户重定向到您的应用程序的双重身份的屏幕验证。但如果您的应用程序发出 XHR 登录请求,则在成功进行身份验证后返回一个包含 two_factor
布尔属性的 JSON 对象。 您可以检查此值以了解是否应该重定向到双重因素的屏幕验证。
要开始实现双重验证功能,我们需要指示 Fortify 如何返回双重验证的视图。 Fortify 的所有身份验证视图渲染逻辑都可以通过 Laravel\Fortify\Fortify 类使用适当的方法进行自定义。 通常,您应该从应用程序的 App\Providers\FortifyServiceProvider
类的 boot
方法中调用此类:
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
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 template variable。或者,在 XHR 请求中,验证错误将通过状态码 422 的 HTTP 响应返回。
禁用双因素认证#
如果要禁用双因素认证,你的应用应该向 /user/two-factor-authentication
发起一个 DELETE 请求。请记住,Fortify 的双因素认证接口在 密码确认 期间被调用。
注册#
为了实现应用的注册功能,我们需要指导 Fortify 如何返回我们的「注册」页面。请记住,Fortify 是一个无界面认证库。如果你想要一个已经为你完成 Laravel 的认证功能的前端实现,你可以使用 应用入门套件.
所有的 Fortify 的界面渲染逻辑都可以利用合适的方法通过 Laravel\Fortify\Fortify
类来定制。 通常,你应该在 App\Providers\FortifyServiceProvider
类的 boot
方法中调用该方法。
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Fortify::registerView(fn () => view('auth.register'));
// ...
}
Fortify 负责定义返回这个界面的 /register
路由。register
模版中应该包含一个可以由 Fortity 定义的可以发起 POST 请求到 /register
接口的表单。
/register
接口接收字符串类型 name
,字符串类型邮箱地址 / 用户名、password
和 password_confirmation
字段。邮箱 / 用户名的字段名应该和你应用的 fortify
配置文件中的 username
配置一致。
如果注册成功,Fortify 会将用户重定向到 fortify
配置文件中的 home
项配置的 URI。如果登录是一个 XHR 请求,将返回 200 HTTP 响应 。
如果请求不成功,用户将被重定向回注册页,验证错误将通过共享的 $errors
Blade 模板变量。或者,对于 XHR 请求,验证错误将与 422 HTTP 响应一起返回。
自定义注册#
可以通过修改安装 Laravel Fortify 时生成的 App\Actions\Fortify\CreateNewUser
操作来自定义用户验证和创建过程。
重设密码#
请求密码重置链接#
要想实现应用的密码重置功能,我们需要指示 Fortify 如何返回我们的 「忘记密码」视图。请记住,Fortify 是一个无标头身份验证库。如果你想要一个已经为你完成的 Laravel 身份验证功能的前端实现,你应该使用一个 应用程序入门工具包。
Fortify 的所有视图渲染逻辑都可以通过 Laravel\Fortify\Fortify
类使用适当的方法进行自定义。通常,您应该从应用程序的 App\Providers\FortifyServiceProvider
类的 boot
方法中调用此方法:
use Laravel\Fortify\Fortify;
/**
* 引导任意应用服务
*
* @return void
*/
public function boot()
{
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
session 变量可用于显示密码重置链接请求尝试的状态。此 session 变量的值将匹配应用程序的 passwords
语言文件 中定义的翻译字符串之一:
@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
方法中调用该方法。
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Fortify::resetPasswordView(function ($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
session 变量将被设置,这样你可以在登录界面展示那个重置成功的状态:
@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\ResetUserPassword
动作来定制。
邮箱验证#
在注册之后,你可能希望用户在进入应用之前能够先验证他们的邮箱。在开始之前,确保 emailVerification
功能在 fortify
配置文件的 features
数组中是打开的 。接着,你要确保你的 App\Models\User
类实现了 Illuminate\Contracts\Auth\MustVerifyEmail
接口。
一旦完成这两步,新注册的用户将收到一个邮件引导他们验证邮箱的归属。然而,我们需要通知 Fortify 如何展示邮件验证界面,告知用户他们需要点击邮件中的验证链接。
所有的 Fortify 的界面渲染逻辑都可以利用合适的方法通过 Laravel\Fortify\Fortify
类来定制。 通常,你应该在 App\Providers\FortifyServiceProvider
类的 boot
方法中调用该方法。
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Fortify::verifyEmailView(fn () => view('auth.verify-email'));
// ...
}
Fortify 负责定义用户被 Laravel 内置的 verified
中间件重定向到 /email/verify
终端的路由。
你的 verify-email
模版应该包含提醒用户发到他们邮箱中的邮箱验证链接的提示语。
重发邮箱验证链接#
如果你希望,你可以添加一个按钮到你应用的 verify-email
模版,这可以触发一个 POST 请求到 /email/verification-notification
服务。 这个服务接收一个请求,一个新的验证邮箱将被发送给用户,这将允许用户获得一个新的验证链接,防止之前的验证链接意外被删除或者丢失。
如果重发验证链接的邮件是成功的,Fortify 将将用户重定向回 /email/verify
,并包含 status
session 变量,这可以让你可以提醒用户这个操作是成功的。如果请求是一个 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
Protecting Routes#
在指定一个路由或者一组路由需要用户验证邮箱地址时,你需要将 Laravel 内置的 verified
中间件添加到路由上。这个中间件在应用的 App\Http\Kernel
类中注册:
Route::get('/dashboard', function () {
// ...
})->middleware(['verified']);
密码确认#
在构建应用程序时,您可能偶尔会执行一些操作,需要用户在执行操作之前确认其密码。 通常,这些路由由 Laravel 内置 password.confirm
中间件保护。
要开始实现密码确认功能,我们需要指示 Fortify 如何返回我们应用程序的 “密码确认” 视图。 请记住,Fortify 是一个无界面身份验证库。 如果你想要一个已经为你完成的 Laravel 身份验证功能的前端实现,你应该使用一个应用入门套件.
Fortify 的所有视图渲染逻辑都可以通过 Laravel\Fortify\Fortify
类来使用适当的方法进行自定义。 通常,您应该从应用程序的 App\Providers\FortifyServiceProvider
类的 boot
方法中调用此方法:
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
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 响应一起返回。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: