Skip to content
Readerstacks logo Readerstacks
  • Home
  • Softwares
  • Angular
  • Php
  • Laravel
  • Flutter
Readerstacks logo
Readerstacks
How to Implement JWT Auth in Laravel

How to Implement JWT Auth in Laravel 9 ?

Aman Jain, May 31, 2022August 20, 2022

JWT (Json Web Token) is used to create the authentication between two parties client and server that means it creates a secure information transactions between two parties. In the process of php-open-source-saver/jwt-auth token it creates a token claims and generates a token behalf of these claims then it verify on each request before processing the activities on application whether its authenticated or not.

Laravel by default uses passport authentication for Rest APIs but we can override it in config file to use the jwt token. Jwt tokens are easy to use and can easily maintain the authenticity of request by JSON token in request.

JWT tokens are signed with HMAC algorithm or private/public key. JWT tokens contains main three parts Header, Payload, signature separated by DOT(.)

In this article of Implement JWT Auth in Laravel I will use PHP php-open-source-saver/jwt-auth package to create jwt token in laravel 9. This package has several methods to attempt, check , refresh and many more.

In this example we will create a simple example to create the json token the library and when a user send a request for login by sending username and password if authentication successful the we will create the token and response back with the token to access the server using auth token. Client can save token in local storage or cookies for later use.

Tokens are time based means token will expire after a time period but we can refresh the token regularly to use it for long time.

Let’s start the tutorial of Implement JWT Auth in Laravel 9 with simple step by step

Step 1: Create a fresh laravel project

Open a terminal window and type below command to create a new project

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

You can also read this to start with new project

Step 2 : Install the package

I assume the you have already installed the laravel and basic connection of it like database connection and composer.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-jwt
DB_USERNAME=root
DB_PASSWORD=

Now install the package using composer in laravel root directory, open the terminal in laravel root directory and run below command to install php-open-source-saver/jwt-auth the package. This package has good stars on github and has lot of fan base of artisans

composer require php-open-source-saver/jwt-auth 

Step 3 : Publish Vendor and Generate Secret Key

Now, publish the configuration files of package

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

this will create a a file in config/jwt.php where you can configure the jwt token configurations.

and generate token using below command

php artisan jwt:secret

this will update a key JWT_SECRET in .env file as below

JWT_SECRET=generated_token

Step 4 : Generate user migration

If you have just installed a fresh project then Create the default table of users in database using the artisan command

php artisan migrate

Now, for an example to access the articles by only authenticated user so i am creating here a table using migration and then i am going to fill the data in it, so create model and migration

php artisan make:model Article -m

this will generate the model and migration file

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasFactory;
    
}

and migration file database/migrations/timestamp_create_articles_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
     public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('email')->unique();;
            $table->string('title');
            $table->string('body')->nullable();
            $table->string('image');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

and then migrate the migration

php artisan migrate

Step 5 : Configure AuthGuard

By default laravel uses its own auth for Rest APIs so we need to change the AuthGuard to Jwt in the config/auth.php


    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

   

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    ],

To

'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],


    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
                'driver' => 'jwt',
                'provider' => 'users',
        ],

    ],

Here we changed default auth to api and also added new guard

'api' => [
                'driver' => 'jwt',
                'provider' => 'users',
        ],

Step 6 : Update User Model

To use the jwt we need to implement two methods in app\Models\User.php class and add getJWTCustomClaims() and getJWTIdentifier() so update the User model as following

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    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 [];
    }
}

and also create a article table and migration so we can access the articles only after login

php artisan make:model Article -m

Above command will create two files one is migration and other one is model. open migration file which is located at database/migrations/timestamp_create_articles_table.php and edit the schema as below

  public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('email')->unique();;
            $table->string('title');
            $table->string('body');
            $table->timestamps();
        });
    }

Run migration using artisan command in command line

php artisan migrate

Output of above command

Migrating: 2021_11_27_112800_create_articles_table
Migrated:  2021_11_27_112800_create_articles_table (45.63ms)

Now create seeder in database/seeders/DatabaseSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

// Import DB and Faker services
use Illuminate\Support\Facades\DB;
use Faker\Factory as Faker;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $faker = Faker::create();

    	for ($i=0;$i<=100;$i++) {
            DB::table('articles')->insert([
                'title' => $faker->name,
                'body' => $faker->text,
                'email' => $faker->email,
                'updated_at' =>$faker->datetime,
                'created_at' => $faker->datetime              
            ]);
        }
        
    }
}

Run Seeder in command line

php artisan db:seed

Step 3 : Create controller

Let’s create a controller and add a methods login, register, refresh and logout

php artisan make:controller AuthController

and add the below code

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\Models\User;

class AuthController extends Controller
{

     
    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|string|email',
            'password' => 'required|string',
        ]);
        $credentials = $request->only('email', 'password');

        $token = Auth::attempt($credentials);
        if (!$token) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized',
            ], 401);
        }

        $user = Auth::user();
        return response()->json([
                'status' => 'success',
                'user' => $user,
                'authorisation' => [
                    'token' => $token,
                    'type' => 'bearer',
                ]
            ]);

    }

    public function register(Request $request){
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = Auth::login($user);
        return response()->json([
            'status' => 'success',
            'message' => 'User created successfully',
            'user' => $user,
            'authorisation' => [
                'token' => $token,
                'type' => 'bearer',
            ]
        ]);
    }

    public function logout()
    {
        Auth::logout();
        return response()->json([
            'status' => 'success',
            'message' => 'Successfully logged out',
        ]);
    }

    public function refresh()
    {
        return response()->json([
            'status' => 'success',
            'user' => Auth::user(),
            'authorisation' => [
                'token' => Auth::refresh(),
                'type' => 'bearer',
            ]
        ]);
    }
    public function articles(){
        return response()->json([
            'status' => 'success',
            'data' => \App\Models\Article::paginate()
            
        ]);
    }

}

Here in above code we have used four methods

Function login : It accepts email and password and if authentication successful then return the user with token.

Function register : To create a new user with email, name and password then response with token.

Function refresh : To refresh the old token.

Function logout : To invalidate the token and logout the user.

Function articles : List of articles with logined user.

Step 4: Create routes in routes/api.php

Create route to login, register, refresh and logout

routes/api.php

<?php

use App\Http\Controllers\ArticleController;
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
 

Route::controller(AuthController::class)>group(function () {
   Route::post('login', 'login');
   Route::post('register', 'register');
});
Route::controller(AuthController::class)->middleware("auth:api")->group(function () {
    Route::post('logout', 'logout');
    Route::post('refresh', 'refresh');
    Route::get('articles', 'articles');
});

I

Postman Screenshot:

Screenshot 2022 05 31 at 10.45.39 PM
Register
Screenshot 2022 05 31 at 10.47.57 PM
Screenshot 2022 05 31 at 10.49.29 PM
Response
Screenshot 2022 05 31 at 10.49.39 PM
Login Respones
Screenshot 2022 05 31 at 11.07.03 PM
List of articles after login
Postman apis for jwt

Response without login:

Screenshot 2022 05 31 at 11.09.29 PM
Accessing apis without login

Note : Make sure to pass header accept : application/json for proper json response in case of unauthntication.

Also Read : How to create multiple size thumbs from image in laravel 8 ?

Related

Php Laravel Laravel 9 authjwtlaravel

Post navigation

Previous post
Next post

Related Posts

Php Simplest Way to Use Roles and Permission in Laravel

Simplest Way to Use Roles and Permission in Laravel

August 23, 2022March 16, 2024

Roles and permission in laravel are used to provide roles based authentication and in this post we will learn simplest wat to use roles and permission in laravel. In our application we want features and modules on basis of roles or permissions so that we can restrict users to access…

Read More
Php How to fetch Soft Deleted Records in Laravel 9

How to Fetch Soft Deleted Records in Laravel ?

June 17, 2022June 21, 2022

In this article we will learn to fetch soft deleted records in Laravel. In our recent article Use Soft Delete to Temporary (Trash) Delete the Records in Laravel ? we learnt to delete the file without actually deleting from database and sometimes we want to show records that are soft…

Read More
Php How to Upload image with preview in Laravel 9 with example

How to Upload image with preview in Laravel 9 with example ?

May 14, 2022May 14, 2022

Upload image with preview in laravel or for any website can be basic requirement like set up a profile picture to providing the documents. Laravel 9 provides robust functionality to upload and process the image with security. Laravel simply use Request file method to access the uploaded file and then…

Read More

Aman Jain
Aman Jain

With years of hands-on experience in the realm of web and mobile development, they have honed their skills in various technologies, including Laravel, PHP CodeIgniter, mobile app development, web app development, Flutter, React, JavaScript, Angular, Devops and so much more. Their proficiency extends to building robust REST APIs, AWS Code scaling, and optimization, ensuring that your applications run seamlessly on the cloud.

Categories

  • Angular
  • CSS
  • Dart
  • Devops
  • Flutter
  • HTML
  • Javascript
  • jQuery
  • Laravel
  • Laravel 10
  • Laravel 11
  • Laravel 9
  • Mysql
  • Php
  • Softwares
  • Ubuntu
  • Uncategorized

Archives

  • June 2025
  • May 2025
  • April 2025
  • October 2024
  • July 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • July 2023
  • March 2023
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021

Recent Posts

  • The Resilience of Nature: How Forests Recover After Fires
  • Understanding Laravel Cookie Consent for GDPR Compliance
  • Understanding High Vulnerabilities: A Critical Overview of the Week of May 12, 2025
  • Installing a LAMP Stack on Ubuntu: A Comprehensive Guide
  • Understanding High Vulnerabilities: A Deep Dive into Recent Security Concerns
©2023 Readerstacks | Design and Developed by Readerstacks
Go to mobile version