Coolify 中的 Laravel Fortify 认证体系:配置项、可覆盖 Action 与关键端点实战解析 📅 发布时间:2026/9/6 23:07:36 👁 浏览次数: Coolify 中的 Laravel Fortify 认证体系配置项、可覆盖 Action 与关键端点实战解析【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify本篇以 Coolify 仓库中的开发技能文档 .agents/skills/fortify-development/SKILL.md 为主体系统讲解 Laravel Fortify 作为无前端headless认证后端在 Coolify 中的落地方式如何通过 config/fortify.php 启用功能特性、如何在app/Actions/Fortify/下覆盖用户创建与密码逻辑、如何用FortifyServiceProvider注册视图回调与响应契约以及登录限流在 RouteServiceProvider 中的真实实现。读完后你可以完整掌握 Fortify 的端点清单、各功能的启用条件并具备在自有 Laravel 项目中复用同一套认证架构的能力。什么是 Fortify无前端认证后端Fortify 是一个 headless 的认证后端它为 Laravel 应用注册认证所需的全部路由与控制器登录、注册、密码重置、邮箱验证、两步验证、Passkey 等但不绑定任何前端视图——界面由应用自己通过视图回调提供。这一设计使 Fortify 既能驱动传统 Blade 页面也能驱动 Livewire、SPA 或纯 API 客户端。Coolify 正是这一模式的典型使用者认证路由与控制器由 Fortify 包注册登录、登出、注册、忘记密码、两步验证挑战等视图层由 app/Providers/FortifyServiceProvider.php 中的Fortify::loginView()、Fortify::registerView()等回调绑定到 Coolify 自有的 Blade 页面如auth.login、auth.register业务逻辑用户创建、密码重置、资料更新集中在 app/Actions/Fortify/ 目录下的四个类中通过契约Contracts注入。从源码结构看Fortify 的扩展点可归纳为五类路由/端点包内注册、Actions可覆盖的业务逻辑、Config特性开关与全局选项、Contracts可覆盖的响应类如LoginResponse、LogoutResponse、RegisterResponse、视图回调在FortifyServiceProvider::boot()中设置。核心配置config/fortify.php 逐项解读Coolify 的 config/fortify.php 展示了 Fortify 的全部关键配置段实际取值如下配置项Coolify 取值作用guardwebFortify 认证所用的 guard必须与 config/auth.php 中的某个 guard 对应SPA 会话认证模式下必须为webpasswordsusers密码重置使用的 broker对应auth.php中的 password brokerusername/email均为email用户名字段所用的模型属性也决定忘记密码/重置请求中预期的字段名homeRouteServiceProvider::HOME登录或重置成功后的跳转路径prefix/domain/null所有 Fortify 路由的前缀与子域名Coolify 使用无前缀默认middleware[web]Fortify 路由挂载的中间件组limiterslogin、two-factor、forgot-password登录、两步验证挑战、忘记密码使用的限流器名称viewstrue是否启用返回视图的路由SPA 项目可设为false只保留 JSON 接口features见下文功能特性开关数组features数组是 Fortify 的功能总开关可用的特性有Features::registration()— 用户注册Features::resetPasswords()— 通过邮箱重置密码Features::emailVerification()— 邮箱验证要求User实现MustVerifyEmail接口Features::updateProfileInformation()— 更新个人资料Features::updatePasswords()— 修改密码Features::twoFactorAuthentication()— 两步验证TOTP带二维码与恢复码可附加选项Features::passkeys()— 基于 WebAuthn 的 Passkey 无密码认证。Coolify 当前启用了其中五项config/fortify.phpfeatures [ Features::registration(), Features::resetPasswords(), // Features::emailVerification(), Features::updateProfileInformation(), Features::updatePasswords(), Features::twoFactorAuthentication([ confirm true, confirmPassword true, // window 0, ]), ],两点值得注意邮箱验证特性被注释掉了。从源码看Coolify 没有让User实现MustVerifyEmailapp/Models/User.php 仅实现了SendsEmail接口而是用自建流程替代自托管部署时用户创建后直接调用markEmailAsVerified()云版本则派发SendVerificationEmailJob见下文CreateNewUser分析。两步验证启用了confirm true与confirmPassword true前者要求用户在启用 2FA 后通过确认步骤二次认证后者在敏感操作前要求再次输入密码。confirm选项还会联动数据库迁移——见下文 2FA 章节。关键端点清单Fortify 注册的完整端点按功能特性启用与否而定如下这是排查认证问题时最常用的一张表功能方法端点登录POST/login登出POST/logout注册POST/register请求密码重置POST/forgot-password执行密码重置POST/reset-password邮箱验证通知GET/email/verify重发验证邮件POST/email/verification-notification密码确认POST/user/confirm-password启用 2FAPOST/user/two-factor-authentication确认 2FAPOST/user/confirmed-two-factor-authentication2FA 挑战POST/two-factor-challenge获取二维码GET/user/two-factor-qr-code恢复码GET/POST/user/two-factor-recovery-codesPasskey 登录选项GET/passkeys/login/optionsPasskey 登录POST/passkeys/loginPasskey 确认选项GET/passkeys/confirm/optionsPasskey 确认POST/passkeys/confirmPasskey 选项GET/user/passkeys/options注册 PasskeyPOST/user/passkeys删除 PasskeyDELETE/user/passkeys/{passkey}开发时可以用php artisan route:list或技能文档中提到的list-routes --only-vendor方式按Fortify控制器筛选快速确认哪些端点在当前特性配置下实际可用。Actions 层四个可覆盖的业务逻辑类Fortify 把认证流程中的业务动作抽象成契约Contracts应用侧在app/Actions/Fortify/提供实现并在 Provider 中注入。Coolify 实现了四个CreateNewUser注册逻辑的重灾区app/Actions/Fortify/CreateNewUser.php 实现CreatesNewUsers契约它包含了三块 Coolify 定制逻辑1注册开关与双重限流。注册前先检查实例级开关再执行自定义限流private const REGISTRATION_IP_MAX_ATTEMPTS 3; private const REGISTRATION_IP_DECAY_SECONDS 600; private const REGISTRATION_EMAIL_IDENTITY_MAX_ATTEMPTS 3; private const REGISTRATION_EMAIL_IDENTITY_DECAY_SECONDS 3600;is_registration_enabled为 false 时直接abort(403)按IP 维度registration:ip:{sha1(ip)}10 分钟内最多 3 次超限abort(429)按归一化邮箱身份维度registration:email-identity:{sha1(...)}1 小时内最多 3 次。normalize_email_identity()辅助函数可剥离别名等变体防止同一个人换邮箱后缀绕过限制。2首个用户即 root 用户。当数据库中尚无任何用户时新用户以id 0强制填充forceFill挂载到预先由 seeder 创建好的 Root TeamTeam::find(0)并赋予owner角色创建完成后立即关闭注册开关is_registration_enabled false保证自托管实例只有第一个注册用户。3邮箱验证策略分流。非首个用户的处理因部署形态而异if (isCloud()) { SendVerificationEmailJob::dispatch($user); } else { $user-markEmailAsVerified(); }验证邮件由 User::sendVerificationEmail() 发出链接使用URL::temporarySignedRoute(verify.verify, ...)生成的临时签名路由有效期取自config(auth.verification.expire, 60)分钟。其余三个 ActionResetUserPassword.php实现ResetsUserPasswords校验新密码满足Password::defaults()且confirmed写入后调用$user-deleteAllSessions()撤销所有已签发会话——这正是重置密码后其他设备掉线的来源UpdateUserPassword.php实现UpdatesUserPasswords要求current_password通过current_password:web校验即对照webguard 的当前密码新密码同样要求Password::defaults()confirmed错误信息使用updatePassword校验 bagUpdateUserProfileInformation.php实现UpdatesUserProfileInformation校验name与emailRule::unique(users)-ignore($user-id)若用户实现了MustVerifyEmail且邮箱变更则清空email_verified_at并重新发送验证通知否则直接落库。FortifyServiceProvider视图回调与响应契约app/Providers/FortifyServiceProvider.php 是 Coolify 定制 Fortify 行为的核心文件分为register()与boot()两部分。register()覆盖 RegisterResponse 契约Fortify 的认证响应通过Laravel\Fortify\Contracts\下的契约类定义可在容器中用自定义实例替换。Coolify 覆盖了RegisterResponse$this-app-instance(RegisterResponse::class, new class implements RegisterResponse { public function toResponse($request) { // First user (root) will be redirected to /settings instead of / on registration. if ($request-user()-currentTeam-id 0) { return redirect()-route(settings.index); } return redirect(RouteServiceProvider::HOME); } });即首个用户root属于id 0的 Root Team注册完成后被导向/settings完成实例初始化其余用户回首页。同理LoginResponse、LogoutResponse等契约也可按同样方式覆盖以实现自定义跳转。boot()视图回调与自定义认证boot()中依次完成注入 ActionsFortify::createUsersUsing(CreateNewUser::class)、Fortify::resetUserPasswordsUsing(...)、Fortify::updateUserProfileInformationUsing(...)、Fortify::updateUserPasswordsUsing(...)注册视图回调Fortify::registerView()— 先检查instanceSettings()-is_registration_enabled关闭则重定向到登录页否则渲染auth.register并传入isFirstUserUser::count() 0标志Fortify::loginView()— 若系统中尚无任何用户直接重定向到注册页否则渲染auth.login并传入注册开关与已启用的 OAuth 供应商列表OauthSetting::where(enabled, true)Fortify::requestPasswordResetLinkView()/Fortify::resetPasswordView()— 分别绑定auth.forgot-password与auth.reset-passwordFortify::confirmPasswordView()/Fortify::twoFactorChallengeView()— 绑定密码确认与 2FA 挑战页。Fortify::authenticateUsing()自定义认证管线。这是 Coolify 最重量级的定制点FortifyServiceProvider.php#L73-L104Fortify::authenticateUsing(function (Request $request) { $email strtolower($request-email); $user User::where(email, $email)-with(teams)-first(); if ($user Hash::check($request-password, $user-password)) { // ... } });其内部还处理了团队邀请的自动接受如果该邮箱存在一个未过期且有效的TeamInvitation用户首次登录时会被自动附加到被邀请的团队携带邀请中的rolecurrentTeam设为该团队并删除邀请记录否则走正常流程——取personal_team作为当前团队缺失时通过recreate_personal_team()重建。最后将currentTeam写入 session。由于 User 模型 的setEmailAttribute会把邮箱统一小写化这里的strtolower与之配合保证大小写不一致时也能登录成功。功能特性启用的完整工作流以下工作流清单继承自技能文档并结合 Coolify 仓库中的实际文件标注了每一步的落点。两步验证2FA给User模型添加TwoFactorAuthenticatable特性 —— Coolify 中位于 app/Models/User.php 的use列表在config/fortify.php的features中启用Features::twoFactorAuthentication()Coolify 附带confirm true、confirmPassword true若缺少*_add_two_factor_columns_to_users_table.php迁移执行php artisan vendor:publish --tagfortify-migrations后再migrate在FortifyServiceProvider中设置Fortify::twoFactorChallengeView()Coolify 已绑定auth.two-factor-challenge构建 2FA 管理界面启用/禁用、恢复码展示测试二维码扫码与恢复码登录流程。Coolify 仓库中已内置对应迁移 database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php无条件添加可空的two_factor_secret与two_factor_recovery_codes两列仅当Fortify::confirmsTwoFactorAuthentication()为真时才添加two_factor_confirmed_at列——这解释了为何 config 中的confirm选项会直接影响数据库结构。User模型也在$hidden中隐藏了two_factor_secret与two_factor_recovery_codes防止敏感字段随 API 序列化泄露。PasskeyWebAuthn给User模型添加PasskeyAuthenticatable特性并实现PasskeyUser接口在config/fortify.php启用Features::passkeys()若缺少 passkeys 表迁移php artisan vendor:publish --tagfortify-migrations并迁移按需配置relying_party_id、allowed_origins、user_handle_secret、timeout等参数默认值不适合生产时基于laravel/passkeys前端包构建注册、登录、确认、删除四种交互界面。Coolify 当前 config/fortify.php 的features中未启用该特性即 Passkey 相关端点/passkeys/login等处于未注册状态。邮箱验证在 config 中启用Features::emailVerification()User模型实现MustVerifyEmail接口设置verifyEmailView回调在受保护路由上挂verified中间件测试注册 → 收信 → 点击验证链接完整流程。再次强调 Coolify 的特殊性它刻意没有启用这一 Fortify 特性config 中被注释而是自实现了自托管即验证、云版本异步验证邮件的分支逻辑并额外提供了邮箱变更验证流程pending_email 6 位验证码 过期时间见 User::requestEmailChange()。密码重置启用Features::resetPasswords()设置requestPasswordResetLinkView回调Coolifyauth.forgot-password设置resetPasswordView回调Coolifyauth.reset-password若禁用了视图需自行定义password.reset命名路由测试申请重置 → 收信 → 链接重置全流程。重置邮件由 User::sendPasswordResetNotification() 发出委托给TransactionalEmails\ResetPassword通知类。SPA 模式views false在config/fortify.php中设置views false安装并配置 Laravel Sanctum 以支撑基于会话的 SPA 认证确保使用webguard会话认证的前提配置好 CSRF 令牌处理测试 XHR 认证流程。当views为false时Fortify 一律返回 JSON 而非重定向。典型场景是 2FA 挑战若已启用两步验证的用户发起登录登录请求会返回{ two_factor: true }前端据此切换到输入 TOTP 码 / 恢复码的挑战界面随后向/two-factor-challenge提交。限流体系从 limiters 配置到真实实现技能文档指出限流通过fortify.limiters.login等配置项指定限流器名称默认按用户名 IP组合节流。Coolify 的完整链路是两段式第一段config/fortify.php 声明名称映射limiters [ login login, two-factor two-factor, forgot-password forgot-password, ],第二段RouteServiceProvider::configureRateLimiting() 给出每个限流器的真实策略RateLimiter::for(login, function (Request $request) { return Limit::perMinute(5)-by((string) $request-email.|.auth_rate_limit_ip($request)); }); RateLimiter::for(two-factor, function (Request $request) { return Limit::perMinute(5)-by($request-session()-get(login.id)); });login每个邮箱 | IP组合每分钟最多 5 次——即技能文档所说的 username IP 组合节流auth_rate_limit_ip()辅助函数统一取 IP可适配代理头two-factor按 session 中暂存的login.id计数每分钟 5 次避免 2FA 挑战接口被暴力猜测 TOTP 码forgot-password双重限流——IP 维度 10 分钟 3 次 归一化邮箱身份维度每小时 3 次与注册限流的邮箱身份思路一脉相承同文件还有magic-link、force-password-reset等 Coolify 自定义限流器供非 Fortify 路由使用。此外CreateNewUser内的注册限流是独立于上述 limiters 的第三层防护因为注册失败路径不经过 Fortify 的限流中间件用RateLimiter::tooManyAttempts()/RateLimiter::hit()手动计数详见上文。最佳实践速查技能文档给出的三条最佳实践在 Coolify 中均有对应实例自定义认证逻辑用Fortify::authenticateUsing()覆盖用户检索方式Coolify 借此实现了邮箱小写化 邀请自动接受用Fortify::authenticateThrough()定制认证管线用AppServiceProvider中的契约绑定覆盖响应跳转Coolify 选择在FortifyServiceProvider::register()中覆盖RegisterResponse注册定制直接修改app/Actions/Fortify/CreateNewUser.php来调整验证规则与附加字段——Coolify 在其中加入了注册开关、双维限流、root 用户初始化与邮箱验证分流限流配置通过fortify.limiters.login换绑限流器名称并在RouteServiceProvider中调整阈值与计数键。小结Fortify 在 Coolify 中的定位是路由与认证管线的提供者而非界面的提供者config/fortify.php决定开启哪些能力与端点app/Actions/Fortify/四个类承载可替换的业务规则FortifyServiceProvider负责把视图、Action 与响应契约接到 Coolify 自己的团队Team模型上。理解这三层扩展点即可在不改动 Fortify 包源码的前提下完成登录跳转定制、注册策略收紧、2FA/Passkey 启用与限流策略调整等常见需求。涉及 TOTP 实现细节、恢复码处理、Passkey 配置项等更深入的包内机制可进一步查阅 Laravel Fortify 官方文档与包源码。【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考