X
    Categories: API Tutorials and Use CasesLearn Laravel Tutorials, Tips And Guides

API Token Creation for Authentication in Laravel 5.2

In this article, I will discuss Laravel API token authentication, a very important topic in web app and website security. I will demonstrate the basis of API token authentication and how easily you could implement the idea in your project.

What is API Token Authentication

The traditional process of interacting with a website is that you login from the login page. Next, you perform you desired actions and then log out. However, in the case of REST API, the process is quite different. The traditional procedure does not work in the case of RESTful APIs because the methods used on login page does not make any sense. You need to use api_token instead.

All you need to do is to append the api_token to the query string before making a request and the  request is authenticated.

Now what Laravel 5.2 offers is quite interesting! You can easily implement this idea using the  TokenGuard library of Laravel.

To demonstrate the idea, I will make a simple application, in which users can register themselves, and by using their api tokens, will try to post some data into the database. If Laravel API Guard allows the token, the  data will be posted to the database. If the token is rejected, an exception is thrown.

Prerequisite

For the purpose of this article, I assume that

  1. You have a Laravel 5.2 app on a Cloudways managed server. If not, sign up now and create a host it for free.
  2. You have executed the following command in the public_html directory of the app
$ php artisan make:auth

If you do not have a Cloudways account, signup here. Check out the guide for setting up a Laravel 5.2 application on Cloudways server.

Create the Database

The first order of business is the creation of the database for the users where the user generated would be posted. This database would be named notes. The users could post data to this database using API and API tokens. These tokens are randomly generated. I will use artisan to create this database.

In the folder public_html/database/migrations,  create this file below. This file will create the user database once I instruct artisan later on.

$ vim 2014_10_12_000000_create_users_table.php
<?php

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;

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('api_token',60)->unique(); //our api token

           $table->rememberToken();

           $table->timestamps('created_at');

       });

   }

   /**

    * Reverse the migrations.

    *

    * @return void

    */

   public function down()

   {

       Schema::drop('users');

   }

}

Now in public_html/database/migrations, create the following file:

$vim 2014_10_12_100000_create_password_resets_table.php
<?php

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;

class CreatePasswordResetsTable extends Migration

{

   /**

    * Run the migrations.

    *

    * @return void

    */

   public function up()

   {

       Schema::create('password_resets', function (Blueprint $table) {

           $table->string('email')->index();

           $table->string('token')->index();

           $table->timestamp('created_at')->nullable();

       });

   }

   /**

    * Reverse the migrations.

    *

    * @return void

    */

   public function down()

   {

       Schema::drop('password_resets');

   }

}

Once done, create another file in the same directory:

$ vim 2016_07_24_153447_create_notes_table.php
<?php

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;

class CreateNotesTable extends Migration

{

   /**

    * Run the migrations.

    *

    * @return void

    */

   public function up()

   {

       Schema::create('notes', function (Blueprint $table) {

           $table->increments('id');

           $table->timestamps('created_at');

           $table->string('text');

           $table->integer('user_id')->unsigned();

           $table->foreign('user_id')->references('id')->on('users');

       });

   }

   /**

    * Reverse the migrations.

    *

    * @return void

    */

   public function down()

   {

       Schema::drop('notes');

   }

}

 

Once done, run the following command in public_html directory. This will create the databases:

$ php artisan migrate

Encapsulate the Routes

I will now create a wrapper that will include a Laravel’s MiddleWare for all the routes that I will use via Token Authentication. Check out the following example:

$ vim app/Http/routes.php
<?php

Route::get('/', function () {

   return view('welcome');

});

//here we are setting that any request with prefix api will be thrown to auth guard

Route::group(['prefix'=>'api','middleware'=>'auth:api'], function(){

   Route::resource('note','NoteController');

});

Route::group(['middleware'=>'web'], function (){

   Route::auth();

   Route::get('/home', 'HomeController@index');

});

I have used the auth middleware for protecting the routes from unauthenticated users. By appending :api, I am simply telling Laravel to switch to the api guard, which is set up in the config/auth.php.

Another important benefit of wrapping the routes in the middleware, the users accessing the API must present the api_token along with the request. Without the api_token, the user will receive specific error.

Make the Controllers

The next step is the creation of controllers.

First, I will make a slight change in the auth controller residing inside the public_html/app/Http/Controller/auth/

$ vim app/Http/Controller/auth/AuthController.php
protected function create(array $data)

   {

       return User::create([

           'name' => $data['name'],

           'email' => $data['email'],

           'api_token' => str_random(60), //slight change here

           'password' => bcrypt($data['password']),

       ]);

   }

 

Next, I will make the  HomeController:

$ vim /app/Http/Controller/HomeController.php
<?php

namespace App\Http\Controllers;

use App\Http\Requests;

use Illuminate\Http\Request;

class HomeController extends Controller

{

   public function __construct()

   {

       $this->middleware('auth');

   }

   public function index()

   {

       return view('home');

   }

}

Once done, I will look into the NoteController that will insert the notes created by the users.

$ vim /app/Http/Controller/NoteController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use Auth;

use App\Note;

class NoteController extends Controller

{

   public function index()

   {

       return response()->json(

           Note::where('user_id',Auth::guard('api')->id())->get()

       );

   }

   public function store(Request $request)

   {

       $note = $request->input('note');

       return Note::create([

           'text'=>$note,

           'user_id'=>Auth::guard('api')->id()

       ]);

   }

   public function show($id)

   {

       return response()->json(

         Note::where('id',$id)

             ->where('user_id',Auth::guard('api')->id())->first()

       );

   }

Make the Models

$ vim /app/Note.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Note extends Model

{

   protected $fillable = ['text', 'user_id',];

   protected $hidden = ['user_id',];

}
$ vim /app/User.php
<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable

{

   protected $fillable = [

       'name', 'email', 'password','api_token',

   ];

   protected $hidden = [

       'password', 'remember_token','api_token',

   ];

}

Testing the App

The app is finished and it is now time to check the functionality of the app. The first step is to register a user. To do this, visit the URL of the application.

Once registered, get the api_token for the user. For this, launch the Database Manager from Application Access Detail page of the Platform. Once launched, you could see the new user and the associated api_token. Copy this token to a text file.

Now I will make a curl POST request:

$ curl -XPOST --data "note=testnote2&api_token=NDm0m8K7xpbjp88dBncspUSTYlGjr6GODV7J61mBrmawofSYlZtUAMtDsRzY" http://phplaravel-14171-55801-148287.cloudwaysapps.com/api/note

 

$ curl -XPOST --data “note=<YOUR NOTE GOES HERE>&api_token=<YOUR COPIED TOKEN GOES HERE” http://<Your APP URL GOES HERE>

If done successfully you will see response similar to this

To test an alternate scenario, make a slight alteration in the api_token. The response will change into this:

Now, I will try out the GET request with the api_token:

$ curl -XGET http://phplaravel-14171-55801-148287.cloudwaysapps.com/api/note/2?api_token=NDm0m8K7xpbjp88dBncspUSTYlGjr6GODV7J61mBrmawofSYlZtUAMtDsRzY

You can change the api_token and you will see that you will be directed to the login page instead of the result.

Conclusion

In this tutorial, I demonstrated how you could use api_token for setting up secure communication within your app. The complete code of the app is located here. If you would like to clarify a point discussed above or would like to extend the conversation, please leave a comment below.

Noor Ali: Noor Ali is an Associate Software Engineer at Cloudways. He loves to solve technical problems through programming and mathematics.