Skip to content

Instantly share code, notes, and snippets.

@nasrulhazim
Last active September 3, 2018 04:54
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save nasrulhazim/febeec1b417096fc68b62eebc47f37c6 to your computer and use it in GitHub Desktop.
Save nasrulhazim/febeec1b417096fc68b62eebc47f37c6 to your computer and use it in GitHub Desktop.
Enable Account Activation in Order to Login to the System.

Before proceed, you may want to follow up Send Welcome Email Notification with Event and Listener.

Step 1

Create new migration script to add activation_token and activated_at column in users table.

php artisan make:migration add_activation_column --table=users

And add as following:

<?php

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

class AddActivationColumn extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('activation_token', 64)->nullable();
            $table->datetime('activated_at')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('activation_token');
            $table->dropColumn('activated_at');
        });
    }
}

Then do migrate:

php artisan migrate

Step 2

Set route to activation. Open up routes/web.php and add the following:

Route::get(
	'account/activate/{token}', 
	'Auth\ActivationController@activate'
)->name('account.activate');

Step 3

Create new controller to handle account activation

php artisan make:controller Auth/ActivationController

And update as following the controller:

<?php

namespace App\Http\Controllers\Auth;

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

class ActivationController extends Controller
{
    public function activate($token)
    {
        // find token based on id
        $user = User::where('activation_token', $token)->first();

        if ($user) {

            // update activation account details
            $user->activation_token = null;
            $user->activated_at = Carbon::now()->format('Y-m-d H:i:s');
            $user->save();

            // login using id
            auth()->loginUsingId($user->id);

            // redirect to home
            return redirect('/home');
        } else {
            return 'Invalid token. <a href="' . route('account.activation.request') . '" >Resend activation email</a>'; 
        }
    }
}

Step 4

Create SendActivationEmailListener listener on user registration by register App\Listeners\SendActivationEmailListener to Illuminate\Auth\Events\Registered in app\Providers\EventServiceProvider.php.

protected $listen = [
    'Illuminate\Auth\Events\Registered' => [
        'App\Listeners\SendActivationEmailListener',
    ],
];
php artisan event:generate

Step 5

Create token for activation and send out account activation email.

<?php

namespace App\Listeners;

use App\Notifications\SendActivationEmail;
use Illuminate\Auth\Events\Registered;

class SendActivationEmailListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  IlluminateAuthEventsRegistered  $event
     * @return void
     */
    public function handle(Registered $event)
    {
        // create a random token
        $token = str_random(64);
        $event->user->activation_token = $token;
        $event->user->save();

        // send notification
        $event->user->notify(
            new SendActivationEmail($token)
        );
    }
}

Step 6

Create new notification

php artisan make:notification SendActivationEmail

And paste the following:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SendActivationEmail extends Notification
{
    use Queueable;

    public $token;
    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->line('Click the button below to activate your account.')
            ->action('Activate',
                route('account.activate', [
                    'token' => $this->token,
                ]))
            ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

Step 7

Now you should be ready to register an account and will receive an email for account activation.

@tenglongroy
Copy link

Registering a listener in app\Providers\EventServiceProvider.php is skipped in this post?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment