>  기사  >  백엔드 개발  >  Laravel 비밀번호 재설정 사용자 정의 마스터하기: 종합 가이드

Laravel 비밀번호 재설정 사용자 정의 마스터하기: 종합 가이드

WBOY
WBOY원래의
2024-09-01 06:31:39215검색

Mastering Laravel Password Reset Customization: A Comprehensive Guide

소개

비밀번호 재설정 기능은 최신 웹 애플리케이션의 중요한 구성 요소입니다. Laravel은 강력한 기본 솔루션을 제공하지만 특정 요구 사항을 충족하거나 사용자 경험을 향상시키기 위해 이 프로세스를 맞춤화해야 하는 경우가 있습니다. 이 튜토리얼에서는 기본 수정부터 고급 기술까지 모든 것을 다루는 Laravel의 비밀번호 재설정 워크플로를 사용자 정의하는 방법에 대해 자세히 알아봅니다.

Laravel 인증의 간략한 역사

사용자 정의에 대해 알아보기 전에 Laravel의 인증 솔루션이 어떻게 발전했는지 알아보기 위해 추억을 빠르게 살펴보겠습니다.

  1. Laravel UI: 수년간 커뮤니티에 도움을 준 Laravel의 완전한 인증 솔루션의 첫 번째 반복입니다.
  2. Laravel Breeze: Tailwind CSS의 인기가 높아지면서 탄생한 Breeze는 최소한의 경량 현대적인 인증 스캐폴딩을 제공했습니다.
  3. Laravel Jetstream: 보다 고급 기능이 필요한 사람들을 위해 2FA 및 팀 관리 기능을 포함한 광범위한 인증을 포함하는 Jetstream이 도입되었습니다.
  4. Laravel Fortify: 모든 프런트엔드와 함께 사용할 수 있는 헤드리스 인증 백엔드로, 개발자가 자신의 UI를 구현할 수 있는 유연성을 제공합니다.

Laravel의 비밀번호 재설정 흐름 이해

Laravel의 비밀번호 재설정 프로세스는 일반적으로 다음 단계로 구성됩니다.

  1. 사용자가 비밀번호 재설정을 요청합니다
  2. 토큰이 생성되어 저장됩니다
  3. 재설정 링크(서명된 URL)가 포함된 이메일이 사용자에게 전송됩니다
  4. 사용자가 링크를 클릭하고 새 비밀번호를 입력합니다
  5. 비밀번호가 업데이트되고 토큰이 무효화됩니다

이 흐름은 대부분의 애플리케이션에 적합하지만 필요에 따라 이 프로세스의 다양한 측면을 사용자 정의할 수도 있습니다.

우리가 만들고 있는 것

이 튜토리얼에서는 사용자 정의된 비밀번호 재설정 흐름을 사용하여 기본 Laravel SaaS(최소) 애플리케이션을 생성합니다. 우리가 다룰 내용은 다음과 같습니다.

  • Breeze를 사용하여 새로운 Laravel 애플리케이션 설정
  • 비밀번호 재설정 URL 맞춤설정
  • 비밀번호 재설정 이메일 내용 수정
  • 비밀번호 재설정 후 성공 알림 추가
  • 변경 사항에 대한 자동화된 테스트 구현 및 사용자 정의

시작하기

새 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

모든 테스트가 통과하면 사용자 지정을 계속할 수 있는 녹색 신호가 표시됩니다.

비밀번호 재설정 URL 사용자 정의

기본적으로 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;
        });
    }
}

Conclusion

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:

  1. Implement rate limiting on password reset requests to prevent abuse.
  2. Add logging for successful and failed password reset attempts for security auditing.
  3. Consider implementing multi-channel notifications (e.g., SMS, push notifications) for critical security events like password resets.
  4. Regularly review and update your password policies to align with current security best practices.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.