Implementasi Email Verification dan Custom Password Reset di Laravel
Berikut adalah tutorial lengkap untuk Email Verification dan Custom Password Reset di Laravel. Namun sebelum ke tutorlal ini, ada baiknya mengikuti tutorial sebelumnya
Persiapan Awal
- Laravel versi terbaru (Laravel 10) harus sudah diinstal.
- Database sudah dikonfigurasi di .env dan tabel sudah dimigrasi.
- Laravel Breeze untuk scaffolding autentikasi juga disarankan. Jika belum, jalankan:
composer require laravel/breeze --dev
php artisan breeze:install
php artisan migrate
Langkah 1: Mengaktifkan Verifikasi Email
1.1 Mengaktifkan Middleware Verifikasi Email
Untuk data user, kita akan pakai data sebelumnya pada tutorial Membuat Multi-Authentication System di Laravel Login Admin dan User. Silahkan mengikuti tutorial sebelumnya untuk detailnya
Tambahkan middleware verified pada route yang ingin dilindungi. Buka routes/web.php:
use Illuminate\Support\Facades\Route;
Route::middleware(['auth', 'verified','role:user'])->group(function () {
Route::get('/user/dashboard', function () {
return view('user.dashboard');
})->name('user.dashboard');
});
Hal ini akan melakukan verifikasi setiap melakukan login yang dikirim ke email.
1.2 Mengaktifkan Fitur Verifikasi di Model User
Di file app/Models/User.php, implementasikan MustVerifyEmail:
use Illuminate\Contracts\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmail
{
// Konfigurasi verifikasi email siap digunakan
}
1.3 Menyesuaikan View Verifikasi Email
Jika ingin mengubah tampilan, buat resources/views/auth/verify-email.blade.php:
@extends('layouts.app')
@section('content')
<div>
<h1>Email Verification</h1>
<p>Check your email to verify your account.</p>
@if (session('status') == 'verification-link-sent')
<p>A new verification link has been sent to your email address.</p>
@endif
<form method="POST" action="{{ route('verification.send') }}">
@csrf
<button type="submit">Resend Verification Email</button>
</form>
</div>
@endsection
1.4 Pengujian Verifikasi Email
Setelah pendaftaran, pengguna akan diminta verifikasi email dan diarahkan ke halaman tersebut. Verifikasi akun dengan mengklik link pada email.
Kita akan menggunakan https://mailtrap.io untuk konfigurasi SMTP mailer nya. jika belum registrasi, silahkan registrasi dan login ke akun mailtrap. Setelah login, buka menu INBOXES lalu ada SMTP untuk kita lakukan testing seperti berikut:
Setelah dapat, edit file .env di laravel menjadi sebagai berikut:
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=304a002842dcf4
MAIL_PASSWORD=********6a30
Sesuaikan config SMTP dengan config SMTP di mailtrap anda. Setelah itu kita akan testing login menggunakan URL berikut:
http://localhost:8000/login
Setelah itu akan muncul verifikasi sebagai sebagai berikut:
Cek di inbox mailtrap, dan akan menghasilkan seperti berikut:
Langkah 2: Mengatur Custom Password Reset
2.1 Membuat Notifikasi Reset Password
Buka file app/Notifications/ResetPasswordNotification.php atau jika belum ada, bisa dibuat dengan:
php artisan make:notification ResetPasswordNotification
Edit ResetPasswordNotification.php untuk menyesuaikan isi email:
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPasswordNotification extends Notification
{
public $token;
public function __construct($token)
{
$this->token = $token;
}
public function via(object $notifiable): array
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Your Password')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', url(route('password.reset', $this->token, false)))
->line('If you did not request a password reset, no further action is required.');
}
}
2.2 Update Model User untuk menggunakan Notifikasi
Di app/Models/User.php, tambahkan method sendPasswordResetNotification:
use App\Notifications\ResetPasswordNotification;
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
2.3 Membuat Route dan View untuk Password Reset
Tambahkan route untuk mengelola password reset di routes/web.php:
use Illuminate\Support\Facades\Password;
use Illuminate\Http\Request;
Route::get('/forgot-password', function () {
return view('auth.forgot-password');
})->middleware('guest')->name('password.request');
Route::post('/forgot-password', function (Request $request) {
$request->validate(['email' => 'required|email']);
$status = Password::sendResetLink(
$request->only('email')
);
return $status === Password::RESET_LINK_SENT
? back()->with(['status' => __($status)])
: back()->withErrors(['email' => __($status)]);
})->middleware('guest')->name('password.email');
Route::get('/reset-password/{token}', function ($token) {
return view('auth.reset-password', ['token' => $token]);
})->middleware('guest')->name('password.reset');
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, $password) {
$user->forceFill([
'password' => bcrypt($password)
])->save();
}
);
return $status === Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
})->middleware('guest')->name('password.update');
2.4 Membuat View untuk Password Reset
Forgot Password View (resources/views/auth/forgot-password.blade.php)
@extends('layout')
@section('content')
<h1>Forgot Password</h1>
<form action="{{ route('password.email') }}" method="POST">
@csrf
<div class="mb-3">
<label for="email" class="form-label">Email:</label>
<input type="email" class="form-control" id="email" name="email" required>
<div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
<button type="submit" class="btn btn-primary mt-50">Send Password Reset Link</button>
</div>
</form>
@endsection
Reset Password View (resources/views/auth/reset-password.blade.php)
@extends('layout')
@section('content')
<h1>Reset Password</h1>
<form action="{{ route('password.update') }}" method="POST">
@csrf
<div class="mb-3">
<input type="hidden" name="token" value="{{ $request->route('token') }}">
<label for="email">Email:</label>
<input type="email" id="email" class="form-control" name="email" required>
</div>
<div class="mb-3">
<label for="password">New Password:</label>
<input type="password" id="password" class="form-control" name="password" required>
</div>
<div class="mb-3">
<label for="password_confirmation">Confirm Password:</label>
<input type="password" id="password_confirmation" class="form-control" name="password_confirmation" required>
</div>
<button type="submit" class="btn btn-primary">Reset Password</button>
</form>
@endsection
Silahkan testing dengan akses URL login kemudian klik Forgot your password? hasilnya seperti berikut:
Jika berhasil, maka akan tampil seperti berikut di inboxes mailtrap:
Setelah klik Reset Password, akan diarahkan ke halaman change password berikut: