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
andJWT_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.