Laravel 6 : Activate Account after Email Verification using Laravel mail

Activate account after email verification:Many web applications require users to verify their email addresses before using the application. Rather than forcing you to re-implement this on each application, Laravel provides convenient methods for sending and verifying email verification requests. But here i am going to customize this basic default auth mechanism.

Laravel provides the Basic Authentication out of the box which includes the basic login, registration, and password reset functionalities. These functionalities can be easily customized. This is the beauty of Laravel framework. In this tutorial we are going to customize the basic registration functionality of the Laravel and acount activation functionality after user registration.

activate-account-after-email-verification

Email Verification and Why It’s Important

Before sending any other email to the address you collected you should always verify that the owner of the email address is the same entity who provided it to you. This is not only helpful to the registrant (as in the "forgot password" scenario described in another answer) and collector (improving the quality of the collection) but also the owner of the email address (especially if this is not the same person as the registrant).

Read more : Form Validation with File Upload in Laravel 6

As someone who has a simple, short gmail email address I get 10 to 20 unsolicited "Thanks (someone else's name) for signing up for our program!" emails each year that are sent from legitimate/non-spam organizations. It doesn't sound like a big deal, but often it takes about 30 minutes of effort to correct this (typically because of having to make a phone call and explain the situation two or three times to different people).

Thankfully I believe this usually happens as the result of an honest mistake. However, what if someone thought it'd be funny to sign me up for a bunch of email lists that I'd surely not want? If the senders don't verify the address first then I'd have a lot of unsubscribing to do later

So, let’s get.

Step 1: Setup route

First we have to create our route. 

routes\web.php

Route::get('/user-register', '[email protected]')->name('register');

Route::post('/user-register', '[email protected]');

Route::get('/user-login', '[email protected]')->name('login');

Route::post('/user-login', '[email protected]');

Route::get('/verify/{token}', '[email protected]')->name('verify');

Step 2: Create a validation trait

Before submitting our form data , we have to validate our input form data. So now create a Trait like following path and paste the following code.

App\Validation\RegisterRequest.php

namespace App\Validation;

use Illuminate\Support\Facades\Validator;

Trait RegisterRequest 
{
    public function inputDataSanitization($data)
    {
        $validator = Validator::make($data, [
           'name' => 'required',
           'email' => 'required',
           'password' => 'required|min:6|confirmed',
        ]);
        
        if($validator->fails()){

         return redirect()->back()->withErrors($validator)->withInput();

        }

        return $validator;
    }
     
     public function loginDataSanitization($data)
    {
        $validator = Validator::make($data, [    
           'email' => 'required',
           'password' => 'required|min:6|confirmed',   
        ]);
        
        if($validator->fails()){

         return redirect()->back()->withErrors($validator)->withInput();

        }

        return $validator;
    }
}

Step 3: Setup RegisterController

App\Http\Controllers\RegisterController.php

namespace App\Http\Controllers\Frontend\Auth;

use App\Http\Controllers\Controller;
use App\Mail\VerificationEmail;
use App\User;
use App\Validation\RegisterRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class RegisterController extends Controller
{   
	use RegisterRequest;

    public function ShowRegisterForm()
    {
    	return view('authentication.register');
    }

    public function HandleRegister(Request $request)
    {
        $this->inputDataSanitization($request->all());

        $user = User::create([
            'name' => trim($request->input('name')),
            'email' => strtolower($request->input('email')),
            'password' => bcrypt($request->input('password')),
            'email_verification_token' => Str::random(32)
        ]);
            
        \Mail::to($user->email)->send(new VerificationEmail($user));

        session()->flash('message', 'Please check your email to activate your account');
       
        return redirect()->back();

    }
}

Step 4: Setup LoginController

App\Http\Controllers\LoginController.php

namespace App\Http\Controllers\Frontend\Auth;

use App\Http\Controllers\Controller;
use App\User;
use App\Validation\RegisterRequest;
use Carbon\Carbon;
use Illuminate\Http\Request;

class LoginController extends Controller
{   
	use RegisterRequest;

     public function ShowLoginForm()
    {
    	return view('authentication.login');
    }

    public function HandleLogin(Request $request)
    {
    	
    	$this->loginDataSanitization($request->except(['_token']));

        $credentials = $request->except(['_token']);

        $user = User::where('email',$request->email)->first();

        if($user->email_verified == 1){

        if (auth()->attempt($credentials)) {

                 $user = auth()->user();

                 $user->last_login = Carbon::now();

                 $user->save();

                 return redirect()->route('home');

            }
           
        }

        session()->flash('message', 'Invalid Credentials');

        session()->flash('type', 'danger');

        return redirect()->back();
    }
}

Step 5: Setup VerifyController

app\Http\Controllers\VerifyController.php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;

class VerifyController extends Controller
{
    public function VerifyEmail($token = null)
    {
    	if($token == null) {

    		session()->flash('message', 'Invalid Login attempt');

    		return redirect()->route('login');

    	}

       $user = User::where('email_verification_token',$token)->first();

       if($user == null ){

       	session()->flash('message', 'Invalid Login attempt');

        return redirect()->route('login');

       }

       $user->update([
        
        'email_verified' => 1,
        'email_verified_at' => Carbon::now(),
        'email_verification_token' => ''

       ]);
       
       	session()->flash('message', 'Your account is activated, you can log in now');

        return redirect()->route('login');

    }

}

Step 6: Create Mail

Now we have to create our mail for sending our token to user. So run below comand to create a mail

php artisan make:mail VerificationEmail

Step 6: Setup VerificationEmail

app\Mail\VerificationEmail.php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class VerificationEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->view('verifyEmail');
    }
}

Step 6: Setup verifyEmail Blade File

resourses\views\verifyEmail.php

Now open your config\mail.php and make your file like below to send mail to user. This is for your local server.

config\mail.php

'driver' => env('MAIL_DRIVER', 'smtp'),

'host' => env('MAIL_HOST', 'mailtrap.io'),

'port' => env('MAIL_PORT', 2525),

Now setup your .env file using your credentilas. Visit here mailtrap to create an account.

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=9e7bb1e65d6ca6
MAIL_PASSWORD=fd8d3a959fa4c3
MAIL_ENCRYPTION=null

Now finally we have to create User table. So open your users table and paste this following code.

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
   
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->timestamp('email_verified_at')->nullable();
            $table->integer('email_verified')->default(0);
            $table->string('email_verification_token');
            $table->string('photo')->nullable();
            $table->timestamp('last_login')->nullable();
            $table->rememberToken();
            $table->softDeletes();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Now everything is ok. So now just we have to create our Login and Register blade template. 

resourses\views\authentication\register.blade.php

resourses\views\authentication\login.blade.php

Now all are ok. So now you can test your app to check email verification before login. Hope it will help you.

A web enthusiastic, self-motivated Full-Stack Web Developer from Dhaka, Bangladesh with experience in developing applications using JavaScript, Laravel & Wordpress specifically. Facebook Github Website