Laravel Fortify
介绍
Laravel Fortify 是一个在Laravel中与前端无关的身份认证后端实现。 Fortify 注册了所有实现 Laravel 身份验证功能所需的路由和控制器, 包括登录、注册、重置密码、邮件验证等。安装 Fortify 后,你可以运行 Artisan 命令 route:list
来查看 Fortify 已注册的路由。
由于 Fortify 不提供其自己的用户界面,因此它应该与你自己的用户界面配对,该用户界面向其注册的路由发出请求。在本文档的其余部分中,我们将进一步讨论如何向这些路由发出请求。
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 的配置(FortifyServiceProvider
)和迁移文件。
下一步,你应该迁移数据库:
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;
/**
* 引导任何应用服务。
*/
public function boot(): void
{
Fortify::loginView(function () {
return view('auth.login');
});
// ...
}
你的登录模板应包括一个向 /login
发出 POST 请求的表单。 /login
表单需要一个 email
/ username
和 password
。 email
/ username
字段与 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;
/**
* 引导应用服务
*/
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 Sanctum 结合使用。
自定义身份验证管道
Laravel Fortify 通过可调用类的管道对登录请求进行身份验证。如果你愿意,你可以定义一个自定义的类管道,登录请求应该通过管道传输。每个类都应该有一个 __invoke
方法,该方法接收传入 Illuminate\Http\Request
实例的方法,并且像 中间件 一样,调用一个 $next
变量,以便将请求传递给管道中的下一个类。
要定义自定义管道,可以使用 Fortify::authenticateThrough
方法。此方法接受一个闭包,该闭包应返回类数组,以通过管道传递登录请求。通常,应该从 App\Providers\FortifyServiceProvider
的 boot
方法调用此方法。
下面的示例包含默认管道定义,你可 以在自己进行修改时将其用作开始:
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 会将你重定向到你应用程序 Fortify
的配置文件中的 home
配置选项的 URI 值。如果登录请求是 XHR 请求,将返回 200 HTTP 响应。用户注销应用程序后,该用户将被重定向到 /
地址。
如果需要对这种行为进行高级定制,可以将 LoginResponse
和 LogoutResponse
契约的实现绑定到 Laravel 服务容器 。通常,这应该在你应用程序的 App\Providers\FortifyServiceProvider
类的 register
方法中完成:
use Laravel\Fortify\Contracts\LogoutResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
/**
* 注册任何应用程序服务。
*/
public function register(): void
{
$this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
public function toResponse(Request $request): RedirectResponse
{
return redirect('/');
}
});
}