密码重置功能是任何现代 Web 应用程序的关键组件。虽然 Laravel 提供了强大的开箱即用解决方案,但有时您需要定制此流程以满足特定要求或增强用户体验。在本教程中,我们将深入探讨自定义 Laravel 的密码重置工作流程,涵盖从基本修改到高级技术的所有内容。
在深入研究定制之前,让我们快速回顾一下 Laravel 的身份验证解决方案是如何演变的:
Laravel 的密码重置过程通常涉及以下步骤:
虽然此流程适用于大多数应用程序,但您可能希望自定义此流程的各个方面以更好地满足您的需求。
在本教程中,我们将创建一个带有自定义密码重置流程的裸 Laravel SaaS(最小)应用程序。我们将涵盖:
让我们开始设置一个新的 Laravel 应用程序:
composer create-project laravel/laravel password-reset-demo cd password-reset-demo
在继续之前,让我们初始化 Git 以进行版本控制:
git init git add . git commit -m "Initial commit"
现在,让我们安装 Laravel Breeze 来获取基本的身份验证脚手架:
composer require laravel/breeze --dev php artisan breeze:install
出现提示时,选择最适合您需求的堆栈。在本教程中,我们将使用 Livewire:
php artisan breeze:install Which Breeze stack would you like to install? ❯ livewire Would you like dark mode support? (yes/no) [no] ❯ no Which testing framework do you prefer? [PHPUnit] ❯ Pest
安装后,让我们提交更改:
git add . git commit -m "Add Authentication and Pages"
现在,设置数据库并运行迁移:
php artisan migrate
安装并编译您的前端资源:
npm install npm run dev
此时,我们已经有了一个具有身份验证功能的基本 Laravel 应用程序。让我们运行测试以确保一切按预期工作:
php artisan test
您应该看到所有测试都通过了,为我们继续进行定制开了绿灯。
默认情况下,Laravel(使用 Breeze)使用标准 URL 进行密码重置(/reset-password)。让我们在 AppServiceProvider 中自定义它:
<?php namespace App\Providers; use App\Models\User; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot(): void { ResetPassword::createUrlUsing(function (User $user, string $token) { return url(route('password.reset', [ 'token' => $token, 'email' => $user->getEmailForPasswordReset(), ], false)); }); } }
此自定义允许您修改重置 URL 结构、添加其他参数,甚至根据需要指向完全不同的域。例如,您可以将其更改为:
return "https://account.yourdomain.com/reset-password?token={$token}&email={$user->getEmailForPasswordReset()}";
接下来,让我们自定义密码重置电子邮件的内容。我们将通过添加到我们的 AppServiceProvider 来做到这一点:
use Illuminate\Notifications\Messages\MailMessage; // ... public function boot(): void { // ... previous customizations ResetPassword::toMailUsing(function (User $user, string $token) { $url = url(route('password.reset', [ 'token' => $token, 'email' => $user->getEmailForPasswordReset(), ], false)); return (new MailMessage) ->subject(config('app.name') . ': ' . __('Reset Password Request')) ->greeting(__('Hello!')) ->line(__('You are receiving this email because we received a password reset request for your account.')) ->action(__('Reset Password'), $url) ->line(__('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')])) ->line(__('If you did not request a password reset, no further action is required.')) ->salutation(__('Regards,') . "\n" . config('app.name') . " Team"); }); }
注意:__() 函数是本地化的助手,可以轻松翻译应用程序中的字符串。
为了增强用户体验和安全性,让我们添加在成功重置密码后发送的通知。首先,创建一个新通知:
php artisan make:notification PasswordResetSuccessfullyNotification
编辑新创建的通知:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class PasswordResetSuccessfullyNotification extends Notification implements ShouldQueue { use Queueable; public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { return (new MailMessage) ->subject('Password Reset Successful') ->greeting('Hello!') ->line('Your password has been successfully reset.') ->line('If you did not reset your password, please contact support immediately.') ->action('Login to Your Account', url('/login')) ->line('Thank you for using our application!'); } }
现在,为PasswordReset事件创建一个监听器:
php artisan make:listener SendPasswordResetSuccessfullyNotification --event=PasswordReset
更新监听器:
<?php namespace App\Listeners; use App\Notifications\PasswordResetSuccessfullyNotification; use Illuminate\Auth\Events\PasswordReset; use Illuminate\Contracts\Queue\ShouldQueue; class SendPasswordResetSuccessfullyNotification implements ShouldQueue { public function handle(PasswordReset $event) { $event->user->notify(new PasswordResetSuccessfullyNotification()); } }
请记住在您的 EventServiceProvider 中注册此侦听器。
测试对于确保我们的定制按预期工作至关重要。更新tests/Feature/Auth/PasswordResetTest.php中现有的密码重置测试:
<?php namespace Tests\Feature\Auth; use App\Models\User; use App\Notifications\PasswordResetSuccessfullyNotification; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Support\Facades\Notification; use Tests\TestCase; class PasswordResetTest extends TestCase { public function test_reset_password_link_can_be_requested(): void { Notification::fake(); $user = User::factory()->create(); $this->post('/forgot-password', ['email' => $user->email]); Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { $response = $this->get($notification->toMail($user)->actionUrl); $this->assertStringContainsString('Reset Password', $response->getContent()); return true; }); } public function test_password_can_be_reset_with_valid_token(): void { Notification::fake(); $user = User::factory()->create(); $this->post('/forgot-password', ['email' => $user->email]); Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { $token = $notification->token; $response = $this->post('/reset-password', [ 'token' => $token, 'email' => $user->email, 'password' => 'new-password', 'password_confirmation' => 'new-password', ]); $response->assertSessionHasNoErrors(); Notification::assertSentTo($user, PasswordResetSuccessfullyNotification::class); return true; }); } public function test_reset_password_email_contains_custom_content(): void { Notification::fake(); $user = User::factory()->create(); $this->post('/forgot-password', ['email' => $user->email]); Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { $mailMessage = $notification->toMail($user); $this->assertStringContainsString('Hello!', $mailMessage->greeting); $this->assertStringContainsString('Regards,', $mailMessage->salutation); return true; }); } }
Customizing Laravel's password reset workflow allows you to create a more tailored and user-friendly experience for your application. We've covered how to modify the reset URL, customize the email content, add a success notification, and ensure everything works through automated testing.
Remember, while customization can be powerful, it's essential to maintain security best practices throughout the process. Always validate user input, use secure token generation and storage methods, and follow Laravel's security recommendations.
Some additional considerations for further improvements:
For more advanced topics and Laravel insights, check out the official Laravel documentation and stay tuned to the Laravel community resources for more in-depth tutorials and best practices.
Happy coding, and may your Laravel applications be ever secure and user-friendly!
以上是掌握 Laravel 密码重置自定义:综合指南的详细内容。更多信息请关注PHP中文网其他相关文章!