Laravel 11 RESTful APIs with JWT Authentication Tutorial

Reading Time: 10 minutes
509 Views

Knowing how to make secure and efficient REST APIs is really important in the fast-moving world of web development. Laravel 11, which is the newest version of a popular tool called PHP framework, gives you a strong starting point for building these types of APIs easily.

When it comes to keeping your APIs safe, using something called JSON Web Tokens (JWT) for authentication is a smart choice. This guide will walk you through the steps of setting up REST APIs with JWT authentication in Laravel 11.

We’ll begin by explaining why REST APIs are so important nowadays and why using JWT authentication matters for keeping your data safe and managing who can access it. Then, we’ll take you through the whole process of getting REST APIs set up with JWT authentication in Laravel 11.

We’ll create APIs for these,

  • User Register API
  • Login API
  • Profile API
  • Refresh Token API
  • Logout API

Let’s get started.

Laravel Installation

Open terminal and run this command to create a laravel project.

composer create-project laravel/laravel myblog

It will create a project folder with name myblog inside your local system.

To start the development server of laravel –

php artisan serve

URL: http://127.0.0.1:8000

Assuming laravel already installed inside your system.

Create Database & Connect

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE laravel_app;

To connect database with application, Open .env file from application root. Search for DB_ and update your details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=root

Install and Create “api.php”

Open project terminal and run this command,

php artisan install:api

It will create “api.php”.

How To Setup JWT (JSON Web Token) in Laravel?

You need to follow few steps to do a successful installation of JWT package in laravel,

Step #1: Add Package

Run composer command,

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

This command install JWT package into application.

Step #2: Publish JWT Config File

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

It will copy a file jwt.php and put into /config folder.

Step #3: Generate JWT Secret Key

php artisan jwt:secret

It will generate a secret key and add into your .env file.

Step #4: Update “auth.php”

Open auth.php file from /config folder.

/*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option defines the default authentication "guard" and password
    | reset "broker" for your application. You may change these values
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'api'),
        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
    ],
/*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | which utilizes session storage plus the Eloquent user provider.
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | Supported: "session"
    |
    */

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

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

Step #5: Update “User.php” model file

Open User.php and update with this code,

<?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 PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use 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',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    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 [];
    }
}

Step #6: Run Migrations (If any pending)

php artisan migrate

It will migrate all pending migrations of application.

Successfully, you have setup JWT auth package into application.

Now, you have a middleware which you can use to protect api routes i.e “auth:api”

API Controller Settings

Run this command to create API controller class,

php artisan make:controller Api/ApiController

It will create a file named ApiController.php inside /app/Http/Controllers folder.

Open file and write this complete code into it,

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;

class ApiController extends Controller
{
    // Register API - POST (name, email, password)
    public function register(Request $request){

        // Validation
        $request->validate([
            "name" => "required|string",
            "email" => "required|string|email|unique:users",
            "password" => "required|confirmed" // password_confirmation
        ]);

        // User model to save user in database
        User::create([
            "name" => $request->name,
            "email" => $request->email,
            "password" => bcrypt($request->password)
        ]);

        return response()->json([
            "status" => true,
            "message" => "User registered successfully",
            //"data" => []
        ]);
    }

    // Login API - POST (email, password)
    public function login(Request $request){

        // Validation
        $request->validate([
            "email" => "required|email",
            "password" => "required"
        ]);

        $token = auth()->attempt([
            "email" => $request->email,
            "password" => $request->password
        ]);

        if(!$token){

            return response()->json([
                "status" => false,
                "message" => "Invalid login details"
            ]);
        }

        return response()->json([
            "status" => true,
            "message" => "User logged in succcessfully",
            "token" => $token,
            //"expires_in" => auth()->factory()->getTTL() * 60
        ]);

    }

    // Profile API - GET (JWT Auth Token)
    public function profile(){

        //$userData = auth()->user();
        $userData = request()->user();

        return response()->json([
            "status" => true,
            "message" => "Profile data",
            "data" => $userData,
            //"user_id" => request()->user()->id,
            //"email" => request()->user()->email
        ]);
    }

    // Refresh Token API - GET (JWT Auth Token)
    public function refreshToken(){

        $token = auth()->refresh();

        return response()->json([
            "status" => true,
            "message" => "New access token",
            "token" => $token,
            //"expires_in" => auth()->factory()->getTTL() * 60
        ]);
    }

    // Logout API - GET (JWT Auth Token)
    public function logout(){
        
        auth()->logout();

        return response()->json([
            "status" => true,
            "message" => "User logged out successfully"
        ]);
    }
}

ApiController class contains the api methods for,

  • Register
  • Login
  • Profile
  • Refresh Token
  • Logout

Setup API Routes

Open api.php file from /routes folder. Add these routes into it,

//...
use App\Http\Controllers\Api\ApiController;

Route::post("register", [ApiController::class, "register"]);
Route::post("login", [ApiController::class, "login"]);

Route::group([
    "middleware" => ["auth:api"]
], function(){

    Route::get("profile", [ApiController::class, "profile"]);
    Route::get("refresh", [ApiController::class, "refreshToken"]);
    Route::get("logout", [ApiController::class, "logout"]);
});

Application Testing

Run this command into project terminal to start development server,

php artisan serve

API #1: Register API

URL – http://127.0.0.1:8000/api/register

Method – POST

Header

Accept:application/json

Form data

{
   "name": "Sanjay Kumar",
   "email": "sanjay.example@gmail.com",
   "password": 123456
   "password_confirmation": 123456
}

Screenshot

API #2: Login API

URL – http://127.0.0.1:8000/api/login

Method – POST

Header

Accept:application/json

Form data

{
   "email": "sanjay.example@gmail.com",
   "password": 123456
}

Screenshot

API #3: Profile API

URL – http://127.0.0.1:8000/api/profile

Method – GET

Header

Accept:application/json
Authorization:Bearer <token>

Screenshot

API #4: Refresh Token API

URL – http://127.0.0.1:8000/api/refresh

Method – GET

Header

Accept:application/json
Authorization:Bearer <token>

Screenshot

API #5: Logout API

URL – http://127.0.0.1:8000/api/logout

Method – GET

Header

Accept:application/json
Authorization:Bearer <token>

That’s it.

We hope this article helped you to learn about Laravel 11 RESTful APIs with JWT Authentication Tutorial in a very detailed way.

Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.