Laravel Lumen with JWT Authentication

About Lumen Framework :

Lumen is an open-source PHP micro-framework for developing REST APIs. It was developed by Taylor Otwell.Lumen is the perfect solution for building Laravel based micro-services and blazing fast APIs.There are many micro-framework in PHP such as Slim and Silex. Lumen is lightweight micro-framework as compared to all other frameworks.

About JWT (JSON Web Based Token):

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Ref : (https://jwt.io/introduction)

Prerequisite:

  • PHP >= 7.1.3
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Mysql >= 5.7
  • Composer (Dependency Manager for PHP)
  • Postman | TelentAPI Extension (For test your endpoints)

Installing:

  • Via Lumen Installer :

composer global require “laravel/lumen-installer”

  • Via Composer Create-Project :

composer create-project laravel/lumen lumen_app “5.8”

  • Enter the project folder :

cd lumen_app

  • Serve the Application:

php -S localhost:8000 -t public

  • Display Folder Structure
  • Open Project in your editor
  • Open .env File and add database credentials

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

  • In boostrap/app.php uncomment the facades and eloquent method

//before

//$app->withFacades();

//$app->withEloquent();

//after

$app->withFacades();

$app->withEloquent();

Make a User Table for migration.

php artisan make:migration create_users_table — create=users

  • Migration files are created in database/migration/ _create_user_table.php directory.
  • Set needed table column in migration file. See below code.

***

public function up()
{
Schema::create(‘users_info’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->string(‘name’,50);
$table->string(‘email’);
$table->text(‘password’);
$table->text(‘access_token’);
$table->string(‘image’, 255);
$table->string(‘contact_no’,12);
$table->json(‘roles’);
$table->enum(‘account_private’, [‘Yes’, ‘No’]);
$table->enum(‘status’, [‘active’, ‘de-active’]);
$table->timestamps();
});
}

***

Migrate your database:

php artisan migrate

  • Register route which as the name implies; register users. Locate routes/web.php and insert the needed code as seen below

$router->group([‘prefix’ => ‘api’], function () use ($router) {

$router->post(‘/register_usr’, ‘UserController@register_user’);
$router->post(‘login’, ‘AuthController@user_login’);
$router->post(‘register’, ‘AuthController@register’);
$router->get(‘profile’, ‘UserController@profile’);
$router->get(‘users/{id}’, ‘UserController@get_single_user’);
$router->get(‘users’, ‘UserController@all_users’);
});

  • Let’s create AuthController
  • Create a file app/Http/Controllers/AuthController.php and populate it with code as seen below.

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use Tymon\JWTAuth\JWTAuth;
use App\Users;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
class AuthController extends Controller {

public function register(Request $request) {
try {

$validator = Validator::make($request->all(), [
‘email’ => ‘required|unique:users,email’,
‘name’ => ‘required’,
‘password’ => ‘required|confirmed’,
‘image’ => ‘required|mimes:jpeg,png,jpg,gif,svg|max:2048’,
],[
‘email.unique’ => ‘Email is already exists!Try another Email’,
‘email.max’ => ‘Email is Required’,
‘name.required’ => ‘Name is Required’,
‘password.required’ => ‘Password is Required’,
‘password.confirmed’ => ‘Passwords does not match’
]);

if ($validator->fails()) {
$response = response()->json([‘data’ => [], ‘message’ => $validator->errors(), 422]);
}else{
$apikey = str_random(40);
$contact_no = $request->contact_no;
$role_data = $request->roles;
$roles = $role_data;
$image = $request->file(‘image’);
$name = time().’.’.$image->getClientOriginalExtension();
$destinationPath = storage_path(‘/app/images’);
$image->move($destinationPath, $name);
$password = $request->password;
$inserted_data = Users::create([
‘name’ => $request->name,
‘email’ => $request->email,
‘password’ => app(‘hash’)->make($password),
‘access_token’ => $apikey,
‘image’ => $name,
‘contact_no’ => $contact_no,
‘roles’ => $roles,
‘status’ => $request->input(‘status’),
‘private’ => $request->input(‘private’),
]);
if ($inserted_data) {
$response = response()->json([‘data’ => [1], ‘message’ => ‘User is Created!’, 200]);
} else {
$response = response()->json([‘data’ => [], ‘message’ => ‘Error in Creation’, 900]);
}

}

} catch (Exception $e) {
$response = response()->json([‘data’ => [], ‘message’ => ‘Exception Occured’, 000]);
}
return $response;
}
}

  • Make Users Model in app/Users.php directory code as seen below:

use Illuminate\Auth\Authenticatable;
use Laravel\Lumen\Auth\Authorizable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;

class Users extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable;

protected $table = ‘users’;
protected $primaryKey = ‘id’;
protected $fillable = [
‘name’, ‘email’, ‘password’,’image’, ‘contact_no’, ‘roles’, ‘status’, ‘private’ , ‘access_token’
];
protected $hidden = [
‘password’,’access_token’
];

}

  • Register a user(use POSTMAN) with route localhost:8001/api/register and you should get a successful response like so:

Implement User login using JWT Authentication.

  • Add JWT authentication package:

composer require tymon/jwt-auth:dev-develop

  • Generate your API secret:

php artisan jwt:secret

  • Create folder config folder then after create auth.php file in that folder as seen below:
config folder structure

<?php

return [
‘defaults’ => [
‘guard’ => ‘api’,
‘passwords’ => ‘users’,
],

‘guards’ => [
‘api’ => [
‘driver’ => ‘jwt’,
‘provider’ => ‘users’,
],
],

‘providers’ => [
‘users’ => [
‘driver’ => ‘eloquent’,
‘model’ => \App\Users::class
]
]
];

  • Make some changes in Users Model code as seen below:

<?php
namespace App;

use Illuminate\Auth\Authenticatable;
use Laravel\Lumen\Auth\Authorizable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;

use Tymon\JWTAuth\Contracts\JWTSubject;

class Users extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable;

protected $table = ‘users’;
protected $primaryKey = ‘id’;
protected $fillable = [
‘name’, ‘email’, ‘password’,’image’, ‘contact_no’, ‘roles’, ‘status’, ‘private’ , ‘access_token’
];
protected $hidden = [
‘password’,’access_token’
];
public function getJWTIdentifier()
{
return $this->getKey();
}

/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}

  • Make some changes to bootstrap/app.php as seen below:

//before
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]);

//After
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);

//$app->register(App\Providers\AppServiceProvider::class);
//$app->register(App\Providers\EventServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);

// Add this line
$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);

  • Make login route in routes/web.php as seen below:

$router->group([‘prefix’ => ‘api’], function () use ($router) {
$router->post(‘login’, ‘AuthController@user_login’);
$router->post(‘register’, ‘AuthController@register’);
});

  • Add a global respondWithToken method to Controller class in app/Http/Controllers/Controller.php. This is so we could access it from any other controller. Code as seen below:

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Laravel\Lumen\Routing\Controller as BaseController;

class Controller extends BaseController
{
protected function respondWithToken($token)
{
return response()->json([
‘token’ => $token,
‘token_type’ => ‘bearer’,
‘expires_in’ => Auth::factory()->getTTL() * 60
], 200);
}
}

  • Add Some Methods in AuthController code as seen below:

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use Tymon\JWTAuth\JWTAuth;
use App\Users;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
class AuthController extends Controller {

public function user_login(Request $request)
{
$credentials = $request->only([‘email’, ‘password’]);
$login = true;
if (! $token = Auth::attempt($credentials,$login)) {
return response()->json([‘message’ => ‘Unauthorized’], 401);
}

return $this->respondWithToken($token);
}

protected function respondWithToken($token)
{
return response()->json([
‘token’ => $token,
‘token_type’ => ‘bearer’,
‘expires_in’ => Auth::factory()->getTTL() * 60
], 200);
}
}

  • Login a user using route localhost:8001/api/login and you should get a successful response like so:

--

--

--

Software Engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Dealing with data in microservice architectures — part 3 — Replication

Developers, Blocking A PR Is Not An Insult!

Setting Up Live Streaming Using YouTube

Integrate AWS Lex With Flutter

Ultimate Leetcode Challenge — Blind List

Build a cryptocurrency chatbot with Python: Meet Sato the cryptobot

Should your enterprise adopt a private cloud?

Modern PHPDoc Annotations

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
SAMEER MISTRY

SAMEER MISTRY

Software Engineer

More from Medium

Creating your own Oauth2 server using Laravel Passport —Implicit grant flow

Deploy a Dockerized Laravel Application to AWS ECS with EC2 Instance Launch type using GitHub…

How to use Laravel’s default user table for Twill CMS authentication.

Permissions in your Laravel API