Laravel 7 REST API using JWT Authentication with Different Model

Gabriel Innocent
6 min readFeb 18, 2021

The beauty of developing applications in Laravel is that there is so much Rapid Application Development (RAD) and you can easily connect the templated to the backend of the application thus making the majority of projects built with Laravel be traditional web applications where HTML is rendered from the server-side using blade components.

However, did you know that you could also build a robust REST API with Laravel alongside the traditional web application? It’s relatively simple to build one and in this tutorial, we’ll build a Laravel REST API using JWT authentication (JSON Web Tokens) while also loging in with a different module rather than the inbuild User module.

Setting Up a Fresh Laravel 7 Project

Install a new Laravel project using Composer’s create-project command:

composer create-project --prefer-dist laravel/laravel laravel7-rest-api-with-jwt

The command above creates a new Laravel project and pulls in all the required dependencies along with it.

Next, set up the database. I used a MySQL database named laravel7-jwt-custome-model and added the database details to the .env file.

.envDB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel7-rest-api-with-jwt
DB_USERNAME=root
DB_PASSWORD=

Finally, we complete the setup process by running our migrations, which creates the default user-related tables in our database.

php artisan migrate

To verify if the setup works properly, start the webserver using the following command and visit http://127.0.0.1:8000.

php artisan serve

You should see a web page come up similar to this:

Laravel 7 inital pages

Set up JWT Authentication Package

We will be using a famous package called jwt-auth to implement token-based authentication in our Laravel 7 project. This package has over 9000 stars on GitHub and the package makes it very easy to create and issue tokens to our users.

Let’s install the package via Composer:

composer require tymon/jwt-auth

After that, add the service provider to the Providers array in your app.php in the config directory:

config/app.php'providers' => [
...
/*
* Package Service Providers...
*/

'Tymon\JWTAuth\Providers\LaravelServiceProvider'


/*
* Application Service Providers...
*/
...

],

Next, also in the app.config file, add the JWTAuth and JWTFactory facades to the aliases array.

'aliases' => [
...
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'
],

After that, we publish the package’s config using the following command:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

Finally, let’s generate a secret key that this package will use to encrypt our tokens:

php artisan jwt:secret

The above command generates an encryption key and sets it in our .env with something like JWT_SECRET=keystring.

Prepare Custome Model for Authentication

For this case we will be using the existing Client model for authentication, therefore, we need to integrate our client model with the jwt-auth package. To do that, we’ll import the Tymon\JWTAuth\Contracts\JWTSubject contract on the client model and define the two required methods, getJWTIdentifier() and getJWTCustomClaims() .

Configure the Auth Guard and Providers

Now we need to have Laravel always use jwt-auth for authentication instead of the traditional session driver.

Set the default guard to api and the API guard’s driver to jwt in app/auth.config like so:

app/config quards and providers

Under the guars point api to 'drive'=>'jwt' and 'provider’=>’clients which you will define user provider

As you can see the clients provider’s model points to App\Client::class . This will enable our auth to pick from client guard rather than user guard.

Define API routes

Now that we’ve installed the package, let’s get to defining the REST API routes for our application.

In Laravel, you should define your API routes in routes/api.php and not on web.php. We will define authentication-related routes here.

routes/api.php<?phpuse Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function () { Route::post('register', 'JWTAuthController@register');
Route::post('login', 'JWTAuthController@login');
Route::post('logout', 'JWTAuthController@logout');
Route::post('refresh', 'JWTAuthController@refresh');
Route::get('profile', 'JWTAuthController@profile');
});

Note: all the routes defined in routes/api.php will be prefixed with api/ by Laravel and auth routes are prefixed with auth. So our /login route is actually /api/auth/login and the same holds for all the other routes.

Define Authentication Logic

Now that we’ve defined the routes, it’s time to define the respective controller methods for all those routes. Let’s create a controller to house all our authentication logic:

php artisan make:controller JWTAuthController

The register logic

The login, profile and logout Logic

And finally the refresh and createToken logic

Before I explain the routes, I would like you to bring your attention to the auth()->guard('api)-> as this will help seperate the logic of traditional Laravel web app with one that has both api and traditional one and using the a different model for authentication

Explanation

  1. Register: This method is used to register a user and is invoked on /api/auth/register route. This method also takes name, email, and password as an input and creates a new user from it.
  2. Login: This method is invoked when the user hits the /api/auth/login endpoint. We check if the provided email and password are correct and return a JSON token in the response. You should use this token for any subsequent requests.
  3. Profile: This method returns the logged-in user’s details. You need to pass your token in the header field to authenticate this request. I’ll be showing you how to do it in the next section.
  4. Refresh Token: It is a good practice to have short-lived tokens. The tokens are only valid for a short period of time and the user needs to get a new token by sending the old one before it expires. Otherwise, the user would have to login again, which will invalidate the old token.
  5. Logout: This API will invalidate the passed token.

Testing using PostMan

We’re done building our API! Let’s test to see if it works. Note that we pass the token as a header field "Authorization:Bearer token" for Profile, Refresh Token, and Logout APIs.

I have tested the API using Postman and here are the results.

Register (/api/auth/register)

Login (/api/auth/login)

Profile (/api/auth/profile)

Refresh Token (/api/auth/refresh)

Logout (/api/auth/logout)

Now that you’ve implemented a jwt authentication using different model

Thanks so much for reading!😋👏👏👏👏

--

--