[身份验证脚手架] 认证路由 | 认证后端控制器与请求
第3章:认证路由
欢迎回来,Web开发者🐻❄️
在前一章中,我们探索了Breeze为登录、注册和个人资料管理提供的精美用户界面。我们看到访问/login
会显示登录表单,/register
会显示注册表单。
但Laravel应用是如何知道在浏览器中输入/login
这样的URL时要显示哪个特定页面的?它如何将这个网址连接到显示表单或处理提交信息的正确代码?这就是认证路由概念的用武之地。
问题:将URL连接到代码
想象您的Web应用是一座城市,每个功能(如登录、创建账户或更改密码)是不同的建筑。要访问这些建筑,人们需要明确的地址。在Web开发中,这些地址称为URL(如http://localhost:8000/login
)。
没有地图或清晰的路标,应用就不知道当用户请求特定URL时应该将他们导向何处。您必须手动告诉它:"如果有人请求/login
,就显示登录表单。如果他们向/login
提交数据,就处理他们的凭据。"对于所有不同的认证操作,这很快就会变得繁琐且难以管理。
这正是Laravel的路由系统,特别是Breeze的认证路由解决的问题。它们充当应用的"路标"和"地图",将每个传入的Web请求定向到专门处理该请求的后端代码(称为"控制器方法")。
什么是路由?(城市地图)
在Laravel中,路由是将特定URL映射到应用中特定操作的方式。可以这样理解:
路由告诉Laravel:“当有人访问/example
时,运行这个
函数"或"当有人向/save-data
提交数据时,运行那个
函数。”
Breeze的认证地图:routes/web.php
和routes/auth.php
安装Breeze时,它会为您设置所有必要的认证路由。这些路由主要位于项目routes/
目录中的两个重要文件:
routes/web.php
:应用用于Web界面的主要路由文件,处理标准的Web请求routes/auth.php
:Breeze专门创建的包含所有认证相关路由的文件
让我们看看routes/web.php
的简化版本:
// 文件:routes/web.php (简化版)
<?phpuse Illuminate\Support\Facades\Route;// 这是您在'/'看到的默认欢迎页面
Route::get('/', function () {return view('welcome');
});// 加载所有Breeze认证路由
require __DIR__.'/auth.php';
理解基本认证路由:登录页面
以登录页面为例。当访问/login
并提交登录表单时,会发生两个不同的操作,每个都由特定路由处理。
Laravel路由可以监听不同类型的HTTP请求:
GET
请求:用于检索或查看资源(如加载页面)POST
请求:用于向服务器提交数据(如提交表单)
1. 显示登录表单(GET /login
)
当在浏览器中输入http://localhost:8000/login
时,会发送GET
请求:
// 文件:routes/auth.php (简化版)
Route::get('login', [AuthenticatedSessionController::class, 'create'])->middleware('guest') // 只有未登录用户可以访问->name('login'); // 为此路由命名
2. 处理登录表单(POST /login
)
填写并提交登录表单时,会发送POST
请求:
Route::post('login', [AuthenticatedSessionController::class, 'store'])->middleware('guest');
工作原理:导航认证地图
不同技术栈的相似路由
无论选择Blade、React、Vue还是Livewire技术栈,Breeze都会设置相似的认证路由。例如Livewire的路由:
// Livewire Volt路由示例
Volt::route('login', 'pages.auth.login')->name('login');
结论
Laravel Breeze的认证路由是引导用户通过应用安全功能的基本"路标"。通过自动定义这些路由,Breeze使您免于设置应用这一基础部分的繁琐任务。
在下一章中,我们将探索控制器方法和请求处理的具体实现。
第4章:认证后端控制器与请求
在前一章中,我们了解到Laravel的路由就像城市地图,将传入的Web请求(如访问/login
或/register
)引导到正确的"建筑"或处理代码。
但当请求到达目的地后会发生什么?谁在建筑内部实际执行工作?这就是认证后端控制器和表单请求的用武之地。它们是应用安全系统的"大脑"和"守门人",处理从用户登录到注册和密码重置的所有事务。
问题:仅接收请求是不够的
想象用户要登录您的应用。他们在表单中输入邮箱和密码并点击"登录"。
- 浏览器发送数据
- Laravel路由系统接收它(感谢第3章!)
- 路由将其定向到正确的后端逻辑
现在服务器已收到用户的邮箱和密码。接下来呢?
- 邮箱格式是否有效?
- 密码长度是否足够?
- 这个邮箱和密码组合是否真的匹配数据库中的用户?
- 如果一切正确,如何将用户标记为"已登录"以访问仪表板?
- 如果他们尝试登录太多次,是否应该暂时阻止?
仅有路由不足以回答这些问题。我们需要专门的PHP代码来安全高效地执行这些复杂任务。这就是控制器和表单请求的工作。
控制器:执行者(“老板"或"厨师”)
在Laravel中,控制器是将相关请求处理逻辑分组到单个位置的PHP类。当路由将传入的Web请求定向到控制器时,会调用该控制器内的特定方法(类中的函数)来处理请求。
将控制器想象成餐厅的"厨师"。当顾客(Web请求)点餐(如"登录"或"注册"等操作)时,厨师确切知道需要什么食材、如何烹饪以及要提供什么。
Laravel Breeze提供了几个与认证相关的控制器,位于app/Http/Controllers/Auth
目录:
AuthenticatedSessionController
:处理用户登录和注销RegisteredUserController
:处理新用户注册PasswordResetLinkController
:处理发送密码重置邮件NewPasswordController
:处理通过重置链接设置新密码EmailVerificationNotificationController
:处理重新发送邮件验证链接VerifyEmailController
:处理验证用户邮箱
让我们以AuthenticatedSessionController
为主要示例。该控制器管理用户登录和注销的整个过程。
示例:AuthenticatedSessionController
当访问/login
(GET
请求)时,路由指向create
方法:
// 文件:app/Http/Controllers/Auth/AuthenticatedSessionController.php(简化版)
namespace App\Http\Controllers\Auth;use App\Http\Controllers\Controller;
use Illuminate\View\View; // 表示返回网页class AuthenticatedSessionController extends Controller
{/*** 显示登录视图*/public function create(): View{// 这行代码告诉Laravel显示'auth.login'视图// 就是我们在第2章看到的'login.blade.php'文件return view('auth.login');}// ... 处理登录/注销的其他方法
}
说明: 这个create()
方法非常简单。它的工作只是显示登录表单。它向用户返回一个View
(网页)。
当用户填写表单并点击"登录"后,浏览器会向/login
发送POST
请求。这次路由指向store
方法:
// 文件:app/Http/Controllers/Auth/AuthenticatedSessionController.php(简化版store方法)
namespace App\Http\Controllers\Auth;use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest; // 我们稍后会讨论这个!
use Illuminate\Http\RedirectResponse; // 表示重定向用户class AuthenticatedSessionController extends Controller
{// ... 上面的create()方法/*** 处理传入的认证请求*/public function store(LoginRequest $request): RedirectResponse{// 1. 认证用户(检查凭据,登录)$request->authenticate(); // 魔法发生在这里!// 2. 重新生成用户会话ID以提高安全性$request->session()->regenerate();// 3. 登录成功后重定向用户到仪表板return redirect()->intended(route('dashboard', absolute: false));}// ... 处理注销的其他方法
}
说明: store()
方法是实际登录过程发生的地方。注意它接受一个LoginRequest $request
作为参数。这对安全和数据处理至关重要,这引出了我们的下一个关键概念!
表单请求:数据守门人(“保镖"或"食材检查员”)
在控制器(厨师)开始烹饪(处理数据)之前,必须确保食材(用户提交的数据)正确且安全可用。这是表单请求的工作。
表单请求是一种特殊的Laravel类(在我们的例子中是LoginRequest
),充当"保镖"或"食材检查员"。它的主要职责是:
- 授权:检查当前用户(或访客)是否被允许执行此操作(对于登录,通常总是
true
) - 验证:检查提交的数据(如邮箱和密码)是否符合您指定的规则(如"邮箱必须是有效的邮箱",“密码必须存在”)
- 准备(可选):有时可以在将数据传递给控制器之前准备数据
通过将验证和授权逻辑放入表单请求,您的控制器保持简洁,只关注主要业务逻辑,使代码更易于阅读和维护。
Breeze提供了几个表单请求,位于app/Http/Requests/Auth
目录:
LoginRequest
:验证用户登录数据
示例:LoginRequest
让我们深入了解AuthenticatedSessionController
使用的LoginRequest
类:
// 文件:app/Http/Requests/Auth/LoginRequest.php(简化版)
namespace App\Http\Requests\Auth;use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth; // 用于认证用户
use Illuminate\Validation\ValidationException; // 用于显示验证错误class LoginRequest extends FormRequest
{/*** 确定用户是否有权发出此请求* 对于登录,任何人都可以尝试登录,所以我们返回true*/public function authorize(): bool{return true;}/*** 获取应用于请求的验证规则*/public function rules(): array{return ['email' => ['required', 'string', 'email'], // 必须存在、是字符串且为有效的邮箱格式'password' => ['required', 'string'], // 必须存在且是字符串];}/*** 尝试验证请求的凭据* 这个方法由控制器调用*/public function authenticate(): void{// Breeze还在这里添加了速率限制(防止太多失败尝试)$this->ensureIsNotRateLimited();// 尝试使用提供的邮箱和密码登录用户if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {// 如果认证失败,记录失败尝试并抛出错误// (用户会看到"这些凭据与我们的记录不匹配")throw ValidationException::withMessages(['email' => __('auth.failed'),]);}// 如果成功,清除任何速率限制尝试}// ... 速率限制的方法(ensureIsNotRateLimited, throttleKey)
}
说明:
authorize()
:对于登录尝试,我们通常允许任何人尝试登录,所以返回true
rules()
:定义实际的验证规则。例如,email
必须是required
(不能为空)、string
和有效的email
格式。如果违反任何规则,Laravel会自动将用户带回登录页面并显示错误消息,甚至不会触及控制器!authenticate()
:这是Breeze添加的自定义方法。它实际上尝试使用Laravel内置的Auth::attempt()
函数登录用户。还包括"速率限制"以防止暴力攻击(太多登录尝试)
控制器和表单请求如何协同工作:登录流程
让我们重新审视登录示例,看看完整的后端编排:
POST /login请求的逐步说明:
- 用户提交表单:浏览器通过
POST
请求将邮箱和密码发送到您的Laravel应用的/login
- 路由匹配:Laravel的路由系统在
routes/auth.php
中找到Route::post('login', [AuthenticatedSessionController::class, 'store'])
定义 - 表单请求接管:在调用
AuthenticatedSessionController@store()
之前,Laravel自动看到store
方法需要一个LoginRequest
。它首先创建LoginRequest
实例并运行其rules()
方法- 验证检查:如果邮箱不是邮箱格式或密码为空,
LoginRequest
会立即将用户带回登录表单并显示错误消息。甚至不会调用AuthenticatedSessionController
!这对安全和性能非常有利
- 验证检查:如果邮箱不是邮箱格式或密码为空,
- 控制器接收已验证数据:如果验证通过,Laravel然后调用
AuthenticatedSessionController@store()
,传递LoginRequest
实例,该实例现在包含所有经过验证的输入数据 - 控制器认证:在
store()
内部,调用$request->authenticate()
。这会执行LoginRequest
类中的authenticate()
方法- 认证检查:
LoginRequest::authenticate()
方法尝试登录用户。如果凭据错误,它会抛出另一个验证异常,并将用户重定向回登录页面,显示"凭据不匹配"错误
- 认证检查:
- 成功和重定向:如果认证成功,
authenticate()
方法完成,会话被重新生成(安全措施),AuthenticatedSessionController
将用户重定向到他们的仪表板
这种关注点分离——路由映射、请求验证和授权、控制器处理——使您的应用健壮、安全且易于管理。
其他认证控制器
Breeze为每个主要认证操作设置了一个控制器。它们都遵循类似的模式:
- 显示表单的
create()
方法(用于GET
请求) - 处理提交数据的
store()
方法(用于POST
请求),通常使用自定义表单请求进行验证和授权 - 用于注销操作的
destroy()
方法
以下是其他关键控制器的快速概述及其功能:
控制器名称 | 关键操作 | 相关路由 |
---|---|---|
RegisteredUserController | create() : 显示注册表单store() : 创建新用户账户 | GET /register , POST /register |
PasswordResetLinkController | create() : 显示"忘记密码"表单store() : 发送重置邮件 | GET /forgot-password , POST /forgot-password |
NewPasswordController | create() : 显示"重置密码"表单store() : 设置新密码 | GET /reset-password/{token} , POST /reset-password |
EmailVerificationNotificationController | store() : 重新发送验证邮件 | POST /email/verification-notification |
VerifyEmailController | __invoke() : 标记邮箱为已验证 | GET /verify-email/{id}/{hash} |
ProfileController | edit() : 显示个人资料表单update() : 更新用户信息destroy() : 删除账户 | GET /profile , PATCH /profile , DELETE /profile |
每个控制器及其关联方法是认证系统的主力,处理特定任务以确保用户访问和数据完整性。ProfileController
虽然不严格属于"认证",但被包含在Breeze中,因为它管理已登录用户的个人信息,这些信息与他们在应用中的身份密切相关。
结论
恭喜!您刚刚探索了Laravel Breeze认证系统的核心。您已经看到控制器如何充当"大脑",接收请求并执行登录或注册等操作的核心逻辑。您还理解了表单请求如何作为重要的"守门人",确保所有传入数据在到达控制器之前都经过验证和授权,使您的应用安全可靠。
这些组件共同构成了服务器端的"安全系统",管理用户访问并保护应用数据。
现在您已经了解了后端如何处理认证,让我们将注意力转回视觉方面。在下一章中,我们将探讨Breeze如何设置应用布局,为所有应用页面提供一致且美观的外观。
概述
本系列文章深入解析了Laravel Breeze的认证系统实现原理。第3章重点介绍了认证路由机制,将URL(如/login)映射到对应的控制器方法,并解释了GET/POST请求的区别。第4章则详细剖析了后端控制器(如AuthenticatedSessionController)如何实际处理用户认证请求,包括表单验证、会话管理和重定向逻辑。通过餐厅和城市地图的类比,生动形象地解释了Laravel认证系统的各个组件如何协同工作,为用户提供完整的登录、注册、密码重置等功能。