Laravel 9 Custom Email Verification Tutorial - TechvBlogs

Laravel 9 Custom Email Verification Tutorial

In this article, You will learn How to send Custom Email Verification in Laravel 9.


Smit Pipaliya - Author - TechvBlogs
Smit Pipaliya
 

1 year ago

TechvBlogs - Google News

In this article, I'll show you how to custom email verification system in laravel 9. You can understand the concept of the laravel 9 auth verify email laravel 9 email verification tutorial step by step. I explained step by step laravel 9 auth verify email. Let's see below the example laravel 9 authentication email verification.

Laravel old version, we are doing the email verification process manually. Still, in laravel 9, they provide a build email verification setup for newly registered users to verify their email before proceeding. You need to make some basic setup with a need to use middleware, routes, and mail configuration.

Let's follow the below step for custom email verification.

Laravel 9 Custom Email Verification Tutorial

1. Install Laravel Project

First, open Terminal and run the following command to create a fresh laravel project:

composer create-project --prefer-dist laravel/laravel custom-email

or, if you have installed the Laravel Installer as a global composer dependency:

laravel new custom-email

 2. Create a Migration Table

We will create a users_verify table and If the email_verified_at column exists in the user's table, then there is no need to add it.

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
class UsersVerify extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users_verify', function (Blueprint $table) {
            $table->integer('user_id');
            $table->string('token');
            $table->timestamps();
        });
  
        // Already column exist in users table then skip this add new column
        Schema::table('users', function (Blueprint $table) {
            $table->boolean('email_verified_at')->default(0);
        });
    }
  
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users_verify');
        
        // Already column exist in users table then skip this add new column
        Schema::table('users', function (Blueprint $table) {
            if (Schema::hasColumn('users', 'email_verified_at')) {
                $table->dropColumn('email_verified_at');
            }
        });
    }
}

3. Create a Model and Update Model

In this step, we need to add the email_verified_at field on the fillable array in the User model and create a new model called UserVerify, as like below:

app/Models/User.php

<?php
  
namespace App\Models;
  
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
  
class User extends Authenticatable
{
    use HasFactory, Notifiable;
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'email_verified_at'
    ];
  
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];
  
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

app/Models/UserVerify.php

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
  
class UserVerify extends Model
{
    use HasFactory;
  
    protected $table = "users_verify";
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    protected $fillable = [
        'user_id',
        'token',
    ];
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

4. Create Routes

In this step, we need to create a custom route for email verification. So open your routes/web.php file and add the following route.

routes/web.hp

<?php
  
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\Auth\AuthController;
  
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
  
Route::get('login', [AuthController::class, 'index'])->name('login');
Route::post('post-login', [AuthController::class, 'postLogin'])->name('login.post'); 
Route::get('registration', [AuthController::class, 'registration'])->name('register');
Route::post('post-registration', [AuthController::class, 'postRegistration'])->name('register.post'); 
Route::get('logout', [AuthController::class, 'logout'])->name('logout');
  
/* New Added Routes */
Route::get('dashboard', [AuthController::class, 'dashboard'])->middleware(['auth', 'verify_email']); 
Route::get('account/verify/{token}', [AuthController::class, 'verifyAccount'])->name('user.verify'); 

5. Create a Controller

In this step, we need to create AuthController. We updated the code on the postRegistration() and verifyAccount() methods. Let's copy as below:

app/Http/Controllers/Auth/AuthController.php

<?php
  
namespace App\Http\Controllers\Auth;
  
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Session;
use App\Models\User;
use App\Models\UserVerify;
use Hash;
use Illuminate\Support\Str;
use Mail; 
  
class AuthController extends Controller
{
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function index()
    {
        return view('auth.login');
    }  
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function registration()
    {
        return view('auth.registration');
    }
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function postLogin(Request $request)
    {
        $request->validate([
            'email' => 'required',
            'password' => 'required',
        ]);
   
        $credentials = $request->only('email', 'password');
        if (Auth::attempt($credentials)) {
            return redirect()->intended('dashboard')
                        ->withSuccess('You have Successfully loggedin');
        }
  
        return redirect("login")->withSuccess('Oppes! You have entered invalid credentials');
    }
    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function postRegistration(Request $request)
    {  
        $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ]);
           
        $data = $request->post();
        $createUser = $this->create($data);
  
        $token = Str::random(64);
  
        UserVerify::create([
              'user_id' => $createUser->id, 
              'token' => $token
            ]);
  
        Mail::send('email.emailVerificationEmail', ['token' => $token], function($message) use($request){
              $message->to($request->email);
              $message->subject('Email Verification Mail');
          });
         
        return redirect("dashboard")->withSuccess('Great! You have Successfully loggedin');
    }
    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function dashboard()
    {
        if(Auth::check()){
            return view('dashboard');
        }
  
        return redirect("login")->withSuccess('Opps! You do not have access');
    }
    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function create(array $data)
    {
      return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password'])
      ]);
    }
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function logout() {
        Session::flush();
        Auth::logout();
  
        return Redirect('login');
    }
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function verifyAccount($token)
    {
        $verifyUser = UserVerify::where('token', $token)->first();
  
        $message = 'Sorry your email cannot be identified.';
  
        if(!is_null($verifyUser) ){
            $user = $verifyUser->user;
              
            if(!$user->email_verified_at) {
                $verifyUser->user->email_verified_at = 1;
                $verifyUser->user->save();
                $message = "Your e-mail is verified. You can now login.";
            } else {
                $message = "Your e-mail is already verified. You can now login.";
            }
        }
  
      return redirect()->route('login')->with('message', $message);
    }
}

6. Create Blade File

Here, we need to create blade files for email only. So let's create one by one file:

resources/views/emails/emailVerificationEmail.blade.php

<h1>Email Verification Mail</h1>
  
Please verify your email with bellow link: 
<a href="{{ route('user.verify', $token) }}">Verify Email</a>

7. Create Middleware

Here, we need to create middleware for verifying whether the user email is verified. So let's create as like below:

php artisan make:middleware VerifyEmail

app/Http/Middleware/IsVerifyEmail.php

<?php
  
namespace App\Http\Middleware;
  
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
  
class VerifyEmail
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if (!Auth::user()->email_verified_at) {
            auth()->logout();
            return redirect()->route('login')
                    ->with('message', 'You need to confirm your account. We have sent you an activation code, please check your email.');
          }
   
        return $next($request);
    }
}

app/Http/Kernel.php

protected $routeMiddleware = [
    ....
    'verify_email' => \App\Http\Middleware\VerifyEmail::class,
];

8. Email Configuration

In this step, we will add email configuration on the .env file, because we will send an email to reset the password link from the controller:

.env

MAIL_DRIVER=smtp
MAIL_HOST=<YOUR SMTP HOST>
MAIL_PORT=<YOUR SMTP PORT>
MAIL_USERNAME=<YOUR SMTP USERNAME>
MAIL_PASSWORD=<YOUR SMTP PASSWORD>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=<YOUR MAIL FROM ADDRESS>

That's It.

Thank you for reading this article.

Read Also: Add Column After A Column In Laravel Migration

Comments (0)

Comment


Note: All Input Fields are required.