본문 바로가기

비밀번호 재설정

업데이트됨

번역일: 2026년 10월 3일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 10월 3일
번역 갱신
2026년 10월 3일

비밀번호 재설정

소개

대부분의 웹 애플리케이션은 사용자가 비밀번호를 잊어버렸을 때 재설정할 수 있는 기능을 제공합니다. 프로젝트마다 이 기능을 매번 처음부터 구현하도록 하는 대신, Laravel은 비밀번호 재설정 링크를 전송하고 안전하게 비밀번호를 재설정할 수 있는 편리한 서비스를 기본으로 제공합니다.

NOTE

빠르게 시작하고 싶으신가요? 새 Laravel 애플리케이션에 애플리케이션 스타터 키트를 설치해 보세요. Laravel 스타터 키트는 비밀번호 찾기 기능을 포함한 전체 인증 시스템의 뼈대를 자동으로 구성해 줍니다.

설정

애플리케이션의 비밀번호 재설정 관련 설정은 config/auth.php 파일에 저장되어 있습니다. 이 파일에서 사용 가능한 옵션들을 꼭 한 번 살펴보시기 바랍니다. 기본적으로 Laravel은 database 드라이버를 사용하도록 설정되어 있습니다.

driver 설정 옵션은 비밀번호 재설정 데이터를 어디에 저장할지를 정의합니다. Laravel은 다음 두 가지 드라이버를 기본 제공합니다.

  • database - 비밀번호 재설정 데이터를 관계형 데이터베이스에 저장합니다.
  • cache - 비밀번호 재설정 데이터를 캐시 기반 저장소에 저장합니다.

드라이버 사전 준비 사항

Database 드라이버

기본 database 드라이버를 사용하려면 애플리케이션의 비밀번호 재설정 토큰을 저장할 테이블이 필요합니다. 일반적으로 이 테이블은 Laravel 기본 마이그레이션인 0001_01_01_000000_create_users_table.php 파일에 이미 포함되어 있습니다.

Cache 드라이버

전용 테이블 없이 비밀번호 재설정을 처리할 수 있는 cache 드라이버도 제공됩니다. 이 드라이버는 사용자의 이메일 주소를 SHA-256으로 해시한 값을 키로 사용해 데이터를 저장합니다.

'passwords' => [ 'users' => [ 'driver' => 'cache', 'provider' => 'users', 'store' => 'passwords', // 선택 사항... 'expire' => 60, 'throttle' => 60, ], ],

artisan cache:clear 명령을 실행할 때 비밀번호 재설정 데이터까지 함께 삭제되는 것을 막고 싶다면, store 설정 키에 별도의 캐시 스토어를 지정할 수 있습니다. 이 값은 config/cache.php에 정의된 스토어 이름과 일치해야 합니다.

모델 준비

Laravel의 비밀번호 재설정 기능을 사용하려면 애플리케이션의 App\Models\User 모델이 Illuminate\Notifications\Notifiable 트레이트를 사용해야 합니다. 일반적으로 새 Laravel 프로젝트에 기본 포함된 App\Models\User 모델에는 이미 이 트레이트가 적용되어 있습니다.

다음으로, App\Models\User 모델이 Illuminate\Contracts\Auth\CanResetPassword 계약(contract)을 구현하고 있는지 확인하세요. 프레임워크에 기본 포함된 App\Models\User 모델은 이미 이 인터페이스를 구현하고 있으며, 인터페이스 구현에 필요한 메서드들은 Illuminate\Auth\Passwords\CanResetPassword 트레이트를 통해 제공됩니다.

신뢰할 수 있는 호스트 설정

기본적으로 Laravel은 HTTP 요청의 Host 헤더 값과 관계없이 모든 요청에 응답합니다. 또한 웹 요청 중 절대 URL을 생성할 때도 이 Host 헤더 값을 그대로 사용합니다.

일반적으로는 Nginx나 Apache 같은 웹 서버 설정에서 지정된 호스트 이름과 일치하는 요청만 애플리케이션으로 전달되도록 구성하는 것이 좋습니다. 하지만 웹 서버를 직접 설정할 수 없는 환경이라면, 애플리케이션의 bootstrap/app.php 파일에서 trustHosts 미들웨어 메서드를 사용해 Laravel이 특정 호스트 이름에만 응답하도록 제한할 수 있습니다. 비밀번호 재설정 기능을 제공하는 애플리케이션이라면 이 설정이 특히 중요합니다.

이 미들웨어 메서드에 대해 더 자세히 알아보려면 TrustHosts 미들웨어 문서를 참고하세요.

라우팅

사용자가 비밀번호를 재설정할 수 있도록 지원하려면 여러 개의 라우트를 정의해야 합니다. 먼저, 사용자가 이메일 주소로 비밀번호 재설정 링크를 요청할 수 있도록 하는 한 쌍의 라우트가 필요합니다. 그다음, 사용자가 이메일로 받은 재설정 링크를 클릭하고 재설정 폼을 작성했을 때 실제로 비밀번호를 변경하는 또 다른 한 쌍의 라우트가 필요합니다.

먼저 비밀번호 재설정 링크를 요청하는 데 필요한 라우트를 정의합니다. 재설정 링크 요청 폼이 담긴 뷰를 반환하는 라우트부터 작성해 보겠습니다.

Route::get('/forgot-password', function () { return view('auth.forgot-password'); })->middleware('guest')->name('password.request');

이 라우트가 반환하는 뷰에는 email 필드를 포함한 폼이 있어야 하며, 사용자는 이 폼을 통해 특정 이메일 주소로 비밀번호 재설정 링크를 요청할 수 있습니다.

다음으로, "비밀번호 찾기" 뷰에서 제출된 폼 요청을 처리하는 라우트를 정의합니다. 이 라우트는 이메일 주소를 검증하고 해당 사용자에게 비밀번호 재설정 요청을 전송하는 역할을 합니다.

use Illuminate\Http\Request; use Illuminate\Support\Facades\Password; Route::post('/forgot-password', function (Request $request) { $request->validate(['email' => 'required|email']); $status = Password::sendResetLink( $request->only('email') ); return $status === Password::ResetLinkSent ? back()->with(['status' => __($status)]) : back()->withErrors(['email' => __($status)]); })->middleware('guest')->name('password.email');

이 라우트를 좀 더 자세히 살펴보겠습니다. 먼저 요청의 email 속성을 검증합니다. 그다음 Laravel에 내장된 "패스워드 브로커"(Password 파사드)를 사용해 사용자에게 비밀번호 재설정 링크를 전송합니다. 패스워드 브로커는 지정된 필드(여기서는 이메일 주소)를 기준으로 사용자를 조회하고, Laravel의 알림 시스템을 통해 재설정 링크를 전송하는 일을 알아서 처리해 줍니다.

sendResetLink 메서드는 "상태" 슬러그를 반환합니다. 이 상태 값은 Laravel의 로컬라이제이션 헬퍼를 사용해 번역함으로써, 요청 처리 결과를 사용자에게 친숙한 문구로 보여줄 수 있습니다. 이 상태 값의 번역은 애플리케이션의 lang/{lang}/passwords.php 언어 파일에 정의되며, 가능한 각 상태 슬러그 값에 대응하는 항목이 passwords 언어 파일 안에 들어 있습니다.

NOTE

기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉터리가 포함되어 있지 않습니다. Laravel의 언어 파일을 직접 수정하고 싶다면 lang:publish Artisan 명령어로 퍼블리시할 수 있습니다.

Password 파사드의 sendResetLink 메서드를 호출할 때 Laravel이 어떻게 애플리케이션 데이터베이스에서 사용자 레코드를 조회하는지 궁금할 수 있습니다. Laravel의 패스워드 브로커는 인증 시스템의 "사용자 프로바이더"를 활용해 데이터베이스 레코드를 조회합니다. 패스워드 브로커가 사용하는 사용자 프로바이더는 config/auth.php 설정 파일의 passwords 설정 배열 안에서 지정됩니다. 커스텀 사용자 프로바이더를 작성하는 방법에 대해 더 알고 싶다면 인증 문서를 참고하세요.

NOTE

비밀번호 재설정 기능을 수동으로 구현할 경우, 뷰와 라우트의 내용은 직접 정의해야 합니다. 필요한 인증 및 검증 로직이 모두 포함된 스캐폴딩이 필요하다면 Laravel 애플리케이션 스타터 키트를 확인해 보세요.

비밀번호 재설정

비밀번호 재설정 폼

이제 사용자가 이메일로 받은 재설정 링크를 클릭하고 새 비밀번호를 입력했을 때, 실제로 비밀번호를 변경하는 데 필요한 라우트를 정의합니다. 먼저 사용자가 재설정 링크를 클릭했을 때 보여줄 재설정 폼 뷰를 반환하는 라우트를 정의합니다. 이 라우트는 이후 비밀번호 재설정 요청을 검증하는 데 사용할 token 파라미터를 전달받습니다.

Route::get('/reset-password/{token}', function (string $token) { return view('auth.reset-password', ['token' => $token]); })->middleware('guest')->name('password.reset');

이 라우트가 반환하는 뷰에는 email 필드, password 필드, password_confirmation 필드, 그리고 라우트에서 전달받은 비밀 $token 값을 담을 숨김(hidden) token 필드가 포함된 폼이 있어야 합니다.

폼 제출 처리

이제 비밀번호 재설정 폼 제출을 실제로 처리하는 라우트를 정의해야 합니다. 이 라우트는 들어온 요청을 검증하고 데이터베이스의 사용자 비밀번호를 업데이트하는 역할을 합니다.

use App\Models\User; use Illuminate\Auth\Events\PasswordReset; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Password; use Illuminate\Support\Str; Route::post('/reset-password', function (Request $request) { $request->validate([ 'token' => 'required', 'email' => 'required|email', 'password' => 'required|min:8|confirmed', ]); $status = Password::reset( $request->only('email', 'password', 'password_confirmation', 'token'), function (User $user, string $password) { $user->forceFill([ 'password' => Hash::make($password) ])->setRememberToken(Str::random(60)); $user->save(); event(new PasswordReset($user)); } ); return $status === Password::PasswordReset ? redirect()->route('login')->with('status', __($status)) : back()->withErrors(['email' => [__($status)]]); })->middleware('guest')->name('password.update');

이 라우트도 좀 더 자세히 살펴보겠습니다. 먼저 요청의 token, email, password 속성을 검증합니다. 그다음 Laravel에 내장된 "패스워드 브로커"(Password 파사드)를 사용해 비밀번호 재설정 요청에 포함된 자격 증명을 검증합니다.

패스워드 브로커에 전달된 토큰, 이메일 주소, 비밀번호가 모두 유효하다면, reset 메서드에 전달한 클로저가 실행됩니다. 이 클로저는 사용자 인스턴스와 재설정 폼에서 입력된 평문 비밀번호를 인자로 받으며, 이 안에서 데이터베이스의 사용자 비밀번호를 업데이트하면 됩니다.

reset 메서드 역시 "상태" 슬러그를 반환합니다. 이 상태 값도 Laravel의 로컬라이제이션 헬퍼를 사용해 번역함으로써 사용자에게 친숙한 메시지로 보여줄 수 있습니다. 이 값의 번역은 마찬가지로 애플리케이션의 lang/{lang}/passwords.php 언어 파일에 정의되며, 각 상태 슬러그 값에 대응하는 항목이 passwords 언어 파일 안에 들어 있습니다. 애플리케이션에 lang 디렉터리가 없다면 lang:publish Artisan 명령어로 생성할 수 있습니다.

여기서도 Password 파사드의 reset 메서드를 호출할 때 Laravel이 어떻게 사용자 레코드를 조회하는지 궁금할 수 있습니다. Laravel의 패스워드 브로커는 인증 시스템의 "사용자 프로바이더"를 활용해 데이터베이스 레코드를 조회하며, 이때 사용되는 프로바이더는 config/auth.php의 passwords 설정 배열에서 지정됩니다. 커스텀 사용자 프로바이더 작성 방법은 인증 문서를 참고하세요.

만료된 토큰 삭제

database 드라이버를 사용하는 경우, 만료된 비밀번호 재설정 토큰은 삭제되지 않고 데이터베이스에 그대로 남아 있습니다. 다음 Artisan 명령어로 이러한 만료된 레코드를 손쉽게 정리할 수 있습니다.

php artisan auth:clear-resets

이 작업을 자동화하고 싶다면 애플리케이션의 스케줄러에 해당 명령어를 등록하는 것을 고려해 보세요.

use Illuminate\Support\Facades\Schedule; Schedule::command('auth:clear-resets')->everyFifteenMinutes();

커스터마이징

ResetPassword 알림 클래스가 제공하는 createUrlUsing 메서드를 사용하면 비밀번호 재설정 링크 URL을 원하는 형태로 커스터마이징할 수 있습니다. 이 메서드는 클로저를 인자로 받으며, 클로저는 알림을 받을 사용자 인스턴스와 비밀번호 재설정 토큰을 전달받습니다. 일반적으로 이 메서드는 애플리케이션의 AppServiceProvider에 있는 boot 메서드에서 호출합니다.

use App\Models\User; use Illuminate\Auth\Notifications\ResetPassword; /** * 애플리케이션 서비스 부트스트랩 */ public function boot(): void { ResetPassword::createUrlUsing(function (User $user, string $token) { return 'https://example.com/reset-password?token='.$token; }); }

재설정 이메일 커스터마이징

사용자에게 비밀번호 재설정 링크를 보낼 때 사용하는 알림 클래스는 손쉽게 변경할 수 있습니다. 먼저 App\Models\User 모델의 sendPasswordResetNotification 메서드를 오버라이드하세요. 이 메서드 안에서는 직접 작성한 알림 클래스를 자유롭게 사용해 알림을 전송할 수 있습니다. 메서드가 전달받는 첫 번째 인자는 비밀번호 재설정 $token이며, 이 토큰 값을 이용해 원하는 형태의 재설정 URL을 만든 뒤 사용자에게 알림을 전송하면 됩니다.

use App\Notifications\ResetPasswordNotification; /** * 사용자에게 비밀번호 재설정 알림을 전송합니다. * * @param string $token */ public function sendPasswordResetNotification($token): void { $url = 'https://example.com/reset-password?token='.$token; $this->notify(new ResetPasswordNotification($url)); }

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 10월 3일