Tuesday, February 28, 2017

How to Secure Laravel Apps with 2FA via SMS

While everyone is concerned about their application's security, few take it seriously and take the plunge. The first thing you'll notice when learning about this is that two factor authentication (2FA) is the go-to solution as a first step.

Although there have been some serious problems with using text messages as a second factor, it's definitely safer than a plain username and password combination, given that many users tend to use popular and easy to guess passwords for critical services such as payments, chat, emails, etc. In this article, we're going to build two factor authentication into a Laravel application using Twilio SMS as the second factor.

Twilio and Laravel

What We're Building

There's a great chance that you're already familiar with the 2FA flow:

  • User visits the login page.

  • He types in an email and a password.

    Login form

  • We send a verification code using the phone number.

    2FA verification code SMS

  • User must type in the received code.

    Type verification code

  • If the code is correct, we log them in. Otherwise, we give them another chance to try logging in.

    Dashboard

The final demo application is up on GitHub.

Installation

I assume you have your development environment already set up. If not, we recommend Homestead Improved for an easy start.

Go ahead and create a new Laravel project using the Laravel installer or via Composer.

laravel new demo

Or

composer create-project --prefer-dist laravel/laravel demo

Edit the .env file and add your database credentials.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=root

Scaffolding Authentication

Before creating our migrations, keep in mind that Laravel has a command to help us scaffold our authentication flow. It generates the following:

  • Login, register and reset password views and controllers.
  • The necessary routes.

Go ahead and run php artisan make:auth from the command line.

Creating Migrations

Update the users migration class and add a country_code and phone fields.

// database/migrations/2014_10_12_000000_create_users_table.php

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->string('country_code', 4)->nullable();
            $table->string('phone')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Every user has a list of tokens (verification codes) that they generated. Run the php artisan make:model Token -m command to generate the model and migration file. The table schema will look like this:

// database/migrations/2016_12_14_105000_create_tokens_table.php

class CreateTokensTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tokens', function (Blueprint $table) {
            $table->increments('id');
            $table->string('code', 4);
            $table->integer('user_id')->unsigned();
            $table->boolean('used')->default(false);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tokens');
    }
}

I limited the verification code to four digits, but you can make it harder to guess by increasing it. We will get back to this point later. Let's run php artisan migrate to create our database.

Continue reading %How to Secure Laravel Apps with 2FA via SMS%


by Younes Rafie via SitePoint

No comments:

Post a Comment