How to configure JWT in Laravel Applications
Tags: laravel, php, jwt
Published: 2021-06-24 13:12:40

JWT installation & Settings

Before we get into this JSON Web Token tutorial, what exactly is a JWT?
In modern web trends, Popularity of single page applications, mobile applications, and RESTful API services, We are no longer spending much time building markup, instead we are building APIs that our front-end applications consume.
Back-end is more about business logic and data, while presentation logic is moved exclusively to the front-end or mobile applications. These changes have led to new ways of implementing authentication in modern applications.

What is a JSON Web Token?

A JSON Web Token is used to send information that can be verified and trusted by means of a digital signature. It comprises a compact and URL-safe JSON object, which is cryptographically signed to verify its authenticity, and which can also be encrypted if the payload contains sensitive information.
Because of its compact structure, JWT is usually used in HTTP Authorization headers or URL query parameters.

How to use JWT authentication approach in Laravel applications?

JWT (Json Web token) to make token based authentication system in Laravel. if we implement everything of jwt authentication system, it’s hard and takes long time. so we decided to use “tymon/jwt-auth” package to integarte quickly to develop jwt authentication system.

tymon/jwt-auth: https://github.com/tymondesigns/jwt-auth
tymon/jwt-auth document: https://jwt-auth.readthedocs.io/en/develop/

    composer require tymon/jwt-auth

https://jwt-auth.readthedocs.io/en/develop/laravel-installation/

Publish the config

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

You should now have a config/jwt.php file that allows you to configure the basics of this package.

Generate secret key

I have included a helper command to generate a key for you:

    php artisan jwt:secret

Update your User model

    <?php
      namespace App;

      use Tymon\JWTAuth\Contracts\JWTSubject;
      use Illuminate\Notifications\Notifiable;
      use Illuminate\Foundation\Auth\User as Authenticatable;

      class User extends Authenticatable implements JWTSubject
      {
      use Notifiable;

      // Rest omitted for brevity

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

Configure Auth guard
inside the config/auth.php file, update the following details

      'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
      ],
      ......
      'guards' => [
        'api' => [
          'driver' => 'jwt',
          'provider' => 'users',
        ],
      ],

Add authentication routes
First let’s add some routes in routes/api.php as follows:
Jwt Authentication:

    Route::post('register', [JwtAuthController::class, 'register'])->name('api.jwt.register');
    Route::post('login', [JwtAuthController::class, 'login'])->name('api.jwt.login');
    Route::group(['middleware' => 'auth:api'], function(){
      Route::get('user', [JwtAuthController::class, 'me'])->name('api.jwt.user');
      Route::get('refresh', [JwtAuthController::class, 'refresh'])->name('api.jwt.refresh');
      Route::get('logout', [JwtAuthController::class, 'logout'])->name('api.jwt.logout');
    });

Create the JwtAuthController:
    php artisan make:controller JwtAuthController

Then add the following:

    <?php
    namespace App\Http\Controllers\Auth;

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

    class JwtAuthController extends Controller
    {
        /**
        * Create a new AuthController instance.
        *
        * @return void
        */
        public function __construct()
        {
            $this->middleware('auth:api', ['except' => ['login', 'register']]);
        }

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

            $user = new User;
            $user->fill($request->all());
            $user->password = bcrypt($request->password);
            $user->save();

            return response()->json([
                'status' => 'success',
                'data' => $user
            ], 200);
        }

        /**
        * Get a JWT via given credentials.
        *
        * @return \Illuminate\Http\JsonResponse
        */
        public function login()
        {
            $credentials = request(['email', 'password']);

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

            return $this->respondWithToken($token);
        }

        /**
        * Get the authenticated User.
        *
        * @return \Illuminate\Http\JsonResponse
        */
        public function me()
        {
            return response()->json(Auth::user());
        }

        /**
        * Log the user out (Invalidate the token).
        *
        * @return \Illuminate\Http\JsonResponse
        */
        public function logout()
        {
            Auth::logout();

            return response()->json(['message' => 'Successfully logged out']);
        }

        /**
        * Refresh a token.
        *
        * @return \Illuminate\Http\JsonResponse
        */
        public function refresh()
        {
            return $this->respondWithToken(Auth::refresh());
        }

        /**
        * Get the token array structure.
        *
        * @param  string $token
        *
        * @return \Illuminate\Http\JsonResponse
        */
        protected function respondWithToken($token)
        {
            return response()->json([
                'access_token' => $token,
                'token_type' => 'bearer',
                'expires_in' => Auth::factory()->getTTL() * 60
            ]);
        }
    }
You should now be able to POST to the login endpoint (e.g. http://localhost:8000/api/login) with some valid credentials and see a response like: 

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
        "token_type": "bearer",
        "expires_in": 3600
    }

This token can then be used to make authenticated requests to your application.