JWT authentication for Lumen 5.6

Recently I have been tinkering with Vue.js to get a taste of it and I decided to create a quick project to get my hands dirty. I decided to create a blog with authentication etc. My main focus was on the frontend so I decided to quickly bootstrap an application in Lumen because of its simplicity and almost zero-configuration development. For the authentication, I decided to go with JWT and this post is going to be a quick write-up on how I integrated that and how anyone can integrate JWT authentication in their APIs. I hope you are excited so let's get started.

First things first, let’s create an empty lumen project. Open up your terminal and run the following command to create a fresh copy of lumen project on your desktop:

composer create-project --prefer-dist laravel/lumen lumen-jwt

Now we need to create the configuration file i.e. .env at the root of directory. Create it by simply copying the content of .env.example to .env:

cd lumen-jwt
cp .env.example .env

Now lets set a few configuration values in our .env file. Open this lumen project in your favorite code editor or IDE and put the below in the .env file:

Remember to set the APP_KEY and JWT_SECRET to your own.

Create a migration file for the users table:

php artisan make:migration create_users_table

Modify the migration file created inside the database/migrations directory to have name, email and password fields. For me the file is database/migrations/2017_09_05_115448_create_users_table.php:

Now let’s define some factory methods that will help us in populating some seed data in the database. Open the file database/factories/ModelFactory.php and modify it to look like below:

Now let’s create the seeder to populate database with some users. Modify database/seeds/UsersTableSeeder.php to look like:

Now let’s register this user seeder in our database seeders. Modify database/seeds/DatabaseSeeder.php to look like this:

Now create the configured database in MySQL and run the following commands inside your terminal to create the users table and add some dummy data respectively:

php artisan migrate
php artisan db:seed

Now your database looks something like this:

If you run into any errors, run the below command to make sure that composer knows about these newly created classes:

composer dump-autoload

Lumen does not have facades and eloquent enabled by default, let’s enable them first by opening the bootstrap/app.php file and uncommenting the following lines:

$app->withFacades();
$app->withEloquent();

Now let’s create the endpoint to generate JWT token. There are tons of libraries out there that will help you with it we will use the one called firebase/php-jwt. Open up your terminal and run the following command to pull it in using composer:

composer require firebase/php-jwt

Now let’s add the endpoint POST /auth/login that will accept the credentials and return a token for us. Let’s register the route first by adding the following route inside routes/web.php file:

<?php
$router->post(
'auth/login',
[
'uses' => 'AuthController@authenticate'
]
);

Now we need the controller AuthController with method authenticate. Inside app/Http/Controllers folder create a new AuthController.php file and put follwoing content inside it:

In a production ready application you will probably have models and helper methods to achieve this but for the sake of brevity let’s put everything inside the controller.

Lets open up your terminal and then run application by running the following command:

php -S localhost:8000 -t public

Now to test our application i am using Postman. Inside postman create a new request to http://localhost:8000/auth/login. When you hist this route by clicking the send button you will get the the token in response body.

Now we need a middleware to protect our routes. Lets create a middleware JwtMiddleware inside app/Http/Middleware folder that will validate provided token and put the following content inside it.

Open the bootstrap/app.php file and register our JwtMiddleware and alias it with jwt.auth or whatever you like.

$app->routeMiddleware([
'jwt.auth' => App\Http\Middleware\JwtMiddleware::class,
]);

Now let’s protect some of our routes. Open the routes file i.e. routes/web.php and put the following routes inside it:

$router->group(
['middleware' => 'jwt.auth'],
function() use ($router) {
$router->get('users', function() {
$users = \App\User::all();
return response()->json($users);
});
}
);

After updaing the routes file test if our request succeeds by hitting http://localhost:8000/users route. This request will fails beacause this is a protected route and require us to provide token.

To make this privious request successful we need to provide the token as query parameter. We can get the token by hitting the following route http://localhost:8000/auth/login inside Postman application. Now that you have the token open the priviously failed request and this time in the Params section create a key token and set it’s value to the token that you received in previous request. And after that send the request to http://localhost/users route and you will get the users list in response.

And that about wraps it up. If you have any questions feel free to leave your comments below.