Laravel 9 JWT Authentication: Complete Guide

Setting up JWT Token-based Authentication in Laravel is easy. The traditional process of interacting with a website is logging in from the login page. Next, you perform your desired actions and then log out. However, in the case of REST API, the process is entirely different. JWT (JSON Web Token) is usually used to send information that can be trusted and verified using a digital signature.

When we can use JSON Web Tokens

Let us say; you have a mobile application that needs to communicate with the server. Now, a server needs to identify with whom they are talking. But unfortunately, HTTP is a stateless protocol. So we need to create a mechanism that resolves our issue: how the server will identify that the user is new or old. Is it already registered with the application or not. Is it authorized a user or not? In that scenario, we can use JWT Authentication.

Laravel JWT Authentication

  1. A user sends a signup post request to the server, and the server creates a user and JWT token on that database and returns a JWT token as a response.
  2. JWT  is stored either in the browser’s local or other storage mechanisms.
  3. When a user makes another request, it needs to append that token in the request header.
  4. The server checked that token, and based on whether the JWT token was valid or not, it returned a response.
  5. Until a user logs out of the application and destroys that token from the local storage, it always checks for it. If the token is valid, then it can access the particular resources.
  6. If the token is destroyed or manipulated, the user redirects to the login screen, and he needs to fill in the username and password.
  7. If the username and password are valid, then in response, it sends a JWT token back to the user. Then, again same procedure, the user stores it in local storage and sends that token for every request to verify with the server that he has a trusted user and can access the particular resources.

As usual, we start this project by installing fresh Laravel.

 Step 1: Install and configure Laravel

Install Laravel by the following command.

composer create-project laravel/laravel jwtauth --prefer-dist

Configure the database.

Now, install the third-party jwtauth package by typing the following command.

composer require tymon/jwt-auth

It will install the package in the vendor folder, and our composer.json file will be updated.

Step 2: Update the config/app.php for the JWT package

Go to the config  >>  app.php file and add the following.

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

To publish the configuration file in Laravel, you need to run the following line of code :

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

Now for token encryption, I need to generate a secret key by running the following line of code :

php artisan jwt:generate

If you find an error like this after hitting the above command.

ReflectionException : Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist

You need to do the following step.

Go to the JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this part of the code. public function handle() { $this->fire(); }

You can find out more about this issue.

Step 3: Register the user into the database.

Migrate the tables into the database by the following command.

php artisan migrate

Now, create two controller files for user registration and authentication.

  1. APIRegisterController.php
  2. APILoginController.php

Please type the following command to generate it.

php artisan make:controller APIRegisterController
php artisan make:controller APILoginController

Also, register the api routes inside routes  >>  api.php file.

Route::post('user/register', 'APIRegisterController@register');
Route::post('user/login', 'APILoginController@login');

First, we code the register function inside the APIRegisterController.php file.

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\User;
use JWTFactory;
use JWTAuth;
use Validator;
use Response;

class APIRegisterController extends Controller
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255|unique:users',
            'name' => 'required',
            'password'=> 'required'
        ]);
        if ($validator->fails()) {
            return response()->json($validator->errors());
        }
        User::create([
            'name' => $request->get('name'),
            'email' => $request->get('email'),
            'password' => bcrypt($request->get('password')),
        ]);
        $user = User::first();
        $token = JWTAuth::fromUser($user);
        
        return Response::json(compact('token'));
    }
}

What I have done is first check the validation, and then if all the form data seems right, it will register the user in the database and return a JWT token. We are generating the token based on the User object. You can create the token from anything you want. You can find more guidance here.

Step 4: Test in Postman.

We are registering the user through postman. So let us do that.

First, we check the validation.

Laravel API Authentication Tutorial

 

Now, fill in your name, email, and password and see if we can get the token or not.

 

Laravel 5.6 JWT Authentication Tutorial

Yikes!! We have successfully registered the user and get back the JWT token. Now save this token in the local storage, and when we need to access any protected resource, pass this token as Auth Bearer to get a request and obtain that route.

Step 5: Login the user.

We have already defined the login route in the api.php file. Now, go to the APILoginController.php file and code the login function.

// APILoginController.php

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Validator;
use JWTFactory;
use JWTAuth;
use App\User;
use Illuminate\Support\Facades\Auth;

class APILoginController extends Controller
{
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255',
            'password'=> 'required'
        ]);
        if ($validator->fails()) {
            return response()->json($validator->errors());
        }
        $credentials = $request->only('email', 'password');
        try {
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }
        return response()->json(compact('token'));
    }
}

If the email and password are correct, we can generate the JWT token. Otherwise, we get an error. Now check this in the POSTMAN and see if we can get the token.

 

Laravel 5.6 API Authentication Tutorial

Step 6: Include middleware to protect the resources.

The /jwt-auth package provides us, by default, two middlewares.

  • jwt.auth
  • jwt.refresh

We need to register these middlewares into the app  >>  Http  >> Kernel.php file.

protected $routeMiddleware = [
...
...
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
]

Define one route that needs to be protected via JWT Token Authentication.

// api.php

Route::middleware('jwt.auth')->get('users', function(Request $request) {
    return auth()->user();
});

Now, log in to the application and get the token. We can use this token in the get request like the following.

Authorization: Bearer {yourtokenhere}

 

And, we are getting the User back. So Our fully functional Laravel JWT Authentication Tutorial Example is working. So, I have put this code on Github. So please check that out as well.

Fork Me

17 thoughts on “Laravel 9 JWT Authentication: Complete Guide”

  1. How to use JWT with multiple Models (also multiple tables). I mean like User and Admin models. Please create the tutorial for this case, thank you!

    Reply
    • Step1: Define logout route in routes/api.php
      Route::group([‘middleware’ => ‘jwt.auth’], function(){
      Route::post(‘auth/logout’, ‘AuthController@logout’);
      });
      Step2: In controller
      public function logout()
      {
      JWTAuth::invalidate();
      return response([
      ‘status’ => ‘success’,
      ‘msg’ => ‘Logged out Successfully.’
      ], 200);
      }

      Reply
  2. Hi,

    I am getting

    {
    “error”: “token_not_provided”
    }

    Even, i am sending Authorization header. Please help. its urgent issue. Needs to resolve ASAP

    Reply
  3. Hello!
    I have cloned you GitHub repository and I have installed your app. When I send POST request to /api/user/register I get error message: SQLSTATE[HY000]: General error: 1364 Field ‘api_token’ doesn’t have a default value.
    How can i fix it?

    Reply
  4. How to use JWT with multiple tables. Authentication details stored in 2 tables. I mean like Staff (Teaching+NonTeaching) and Student Tables.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.