Implementing JWT authentication in Laravel application

In today’s digital landscape, securing user authentication has become a top priority for web developers. One popular method to achieve this is JSON Web Token (JWT) authentication.

In this tutorial, we will walk you through the implementation of JWT authentication in Laravel, a powerful PHP framework. By the end, you’ll have a solid understanding of how to integrate JWT into your Laravel application for secure user authentication.

What is JWT Authentication?

JSON Web Token (JWT) is an open standard for securely transmitting information between parties as a JSON object. It consists of three parts: a header, a payload, and a signature. The header and payload are Base64Url encoded JSON objects, and the signature is used to verify the integrity of the token. JWTs are self-contained, meaning all the necessary information is included within the token itself.

Before we dive into JWT authentication, let’s assume you have a Laravel project up and running.

Installing Required Packages

To enable JWT authentication in Laravel, we need to install the tymon/jwt-auth. Open the terminal in root directory of your application and run the below command:

composer require tymon/jwt-auth

Once the package is installed, add the JWT service provider to your config/app.php file by appending the following line to the providers array:

'providers' => [
    // Other providers
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],

Configuring JWT Authentication

Next, generate the JWT configuration file by running the following command:

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

This command will create a config/jwt.php file where you can configure various aspects of JWT authentication, including the token expiration time and the secret key. The sample file looks like below example:

return [
    'secret' => env('JWT_SECRET'),
    'ttl' => env('JWT_TTL', 60),
    'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
    'algo' => env('JWT_ALGO', 'HS256'),
    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
    'providers' => [
        'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
        'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
        'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
    ],
    'required_claims' => [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti',
    ],
    'persistent_claims' => [
        // Add any custom persistent claims here
    ],
    'lock_subject' => true,
];

Generating JWT Secret Key

To generate a unique JWT secret key for your application, run the following command:

php artisan jwt:secret

This command will update your .env file with the generated secret key.

Implementing JWT Authentication on Model

In Laravel, user authentication requires a user model and a corresponding database table. With Laravel project User model is by default loaded. If your project requirement needs to implement authentication on a separate model then create a new model and perform these steps for that particular model.

Now, let’s implement JWT authentication in Laravel. Firstly, we need to configure the User model to make use of JWT. Open the User model file (app/Models/User.php) and add the JWTSubject trait and its required methods:

<?php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;
    use HasFactory;
    
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }
}

These methods are required to retrieve the user’s unique identifier and any additional claims you might want to include in the JWT payload.

Creating the Authentication Controller

To handle user authentication, we’ll create an authentication controller. Run the following command to generate the controller:

php artisan make:controller AuthController

Open the AuthController file from the app/Http/Controllers directory and add the necessary methods for user registration, login, and token retrieval. Here’s an example:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Facades\JWTAuth;
use App\Models\User;

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

        $user = User::create([
            'name' => $validatedData['name'],
            'email' => $validatedData['email'],
            'password' => bcrypt($validatedData['password']),
        ]);

        $token = JWTAuth::fromUser($user);

        return response()->json(['token' => $token], 201);
    }

    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

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

        return response()->json(['token' => $token]);
    }

    public function getAuthToken(Request $request)
    {
        $token = JWTAuth::getToken();

        if (!$token) {
            return response()->json(['error' => 'Token not provided'], 401);
        }

        $token = JWTAuth::refresh($token);

        return response()->json(['token' => $token]);
    }
}

Configuring Routes

Lastly, configure the routes to map the authentication endpoints to the respective methods in the AuthController. Open the routes/api.php file and add the following route definitions:

Route::post('register', 'AuthController@register');

Route::post('login', 'AuthController@login');

Route::get('token', 'AuthController@getAuthToken')->middleware('auth:api');

Testing the Application

For testing, you can use Postman. Create API requests in Postman for the above routes using appropriate methods like register and login routes required post method. However,/token endpoint needs to get a request.

  • To register a new user: /register
  • To log in: /login
  • To get a new token (requires authentication): /token

Conclusion

In this tutorial, we have implemented JWT authentication in the Laravel application. It contains essential steps, from setting the project to performing the register or authentication process. However, you can customize functionality as per your requirements.