Laravel 5.6 JWT Auth for API

6 5,545

In this article, we will discuss Laravel 5.6 JWT Auth. Firstly, you need to know what is JWT. JWT (JSON Web Tokens), it allows us to represent user data in a secure manner. JWT Authentication is used when we work with API. When user sign-in using its own email and password after the successful login credentials, the Token is returned.

This Token is used in the further APIs call. You need to send this Token in your header. Then you can easily access your protected APIs. I’m assuming you are familiar with the Laravel framework if not then you can start with given tutorials.

Setup JWT Auth

Update your composer.json located at root folder.

"require": {
  ...
  "tymon/jwt-auth": "^1.0.0-rc.2"
  ...
}

After updating composer.json, execute the given command. Then tymon/jwt-auth package is included in our vendor directory.

Now, it’s time to update the app providers and aliases.

// add in providers array
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,

// add in alises array
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class

Publish the package assets

We need to publish the assets of this package. You can use the given methods.

Method 1: You can use vendor:publish artisan command and select the provider from the given list. For example:

php artisan vendor:publish

JWT Auth

Method 2: You can use –provider with the vendor publish command. For example:

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

Create JWT Secret

We will use jwt:secret artisan command to create a unique JWT_SECRET key. Which is stored in our .env file located at Laravel App root.

php artisan jwt:secret

Register Middleware

Now, time to register the jwt.auth and jwt.refresh middleware in app/http/Kernel.php

'jwt.auth' => Tymon\JWTAuth\Middleware\Authenticate::class,
'jwt.refresh' => Tymon\JWTAuth\Middleware\RefreshToken::class,

Update User Model

<?php
namespace App;

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

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

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

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];


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

Setup App Routes

Open your routes/api.php, and update the given API routes.

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

Route::middleware('jwt.auth')->group(function(){
    
    Route::get('logout', 'API\AuthController@logout');

});

Setup AuthController

Now, time to create AuthController which contains our logic to perform the authentication using JWT Auth.

php artisan make:controller API/AuthController

After, execution of above command AuthController is located at app/Http/API directory. Then you can add your logic, as given below.

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use JWTAuth;
use Validator;

class AuthController extends Controller
{

    /**
     * API Login, on success return JWT Auth token
     * @param Request $request
     * @return JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');
        $rules = [
            'email' => 'required|email',
            'password' => 'required',
        ];
        $validator = Validator::make($credentials, $rules);
        if($validator->fails()) {
            return response()->json([
                'status' => 'error', 
                'message' => $validator->messages()
            ]);
        }

        try {
            // Attempt to verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json([
                    'status' => 'error', 
                    'message' => 'We can`t find an account with this credentials.'
                ], 401);
            }
        } catch (JWTException $e) {
            // Something went wrong with JWT Auth.
            return response()->json([
                'status' => 'error', 
                'message' => 'Failed to login, please try again.'
            ], 500);
        }
        // All good so return the token
        return response()->json([
            'status' => 'success', 
            'data'=> [
                'token' => $token
                // You can add more details here as per you requirment. 
            ]
        ]);
    }

    /**
     * Logout
     * Invalidate the token. User have to relogin to get a new token.
     * @param Request $request 'header'
     */
    public function logout(Request $request) 
    {
        // Get JWT Token from the request header key "Authorization"
        $token = $request->header('Authorization');

        // Invalidate the token
        try {
            JWTAuth::invalidate($token);
            return response()->json([
                'status' => 'success', 
                'message'=> "User successfully logged out."
            ]);
        } catch (JWTException $e) {
            // something went wrong whilst attempting to encode the token
            return response()->json([
              'status' => 'error', 
              'message' => 'Failed to logout, please try again.'
            ], 500);
        }
    }
}

I’m using Postman to test my API. Its a wonderful tool for testing API.

Result for Login API:

It’s a POST Method API http://localhost/lara-jwt-auth/public/api/login. Successful attempt to return a token which is used in future API calls.

JWT Auth Login API

Result for Logout API:

It’s a GET Method API, we are sending a token with the API call. After that, the token is invalidated so the user can’t use this for other API calls.

JWT Auth Logout API

Conclusion

In this article, we are discussing the basic implementation of JWT Auth in Laravel. It’s a simple and easy to use token-based authentication system. You can download the full example from GitHub. We will discuss more on Token Base Authentication in the future. For example, Laravel Built-In API Authentication Passport, Custom API Authentication, and more on JWT features. Please feel free to add the comment if any query.

Leave A Reply

Your email address will not be published.

6 Comments
  1. Tim Head says

    Hi

    Thanks for the article on this. I am still hoping the official docs are released soon 😉 Small typo in your Register Middleware code example.

    “`
    ‘jwt.refresh’ => Tymon\JWTAuth\Middleware\RefreshToken::class270,
    “`
    Should probably be:

    “`
    ‘jwt.refresh’ => Tymon\JWTAuth\Middleware\RefreshToken::class,
    “`

    1. Code Briefly says

      Thanks Tim

  2. Larry says

    Running Laravel 5.6 I had to undo the following step:

    Register Middleware

    Now, time to register the jwt.auth and jwt.refresh middleware in app/http/Kernel.php

    ‘jwt.auth’ => Tymon\JWTAuth\Middleware\Authenticate::class,
    ‘jwt.refresh’ => Tymon\JWTAuth\Middleware\RefreshToken::class,

    1. Code Briefly says

      Hi Larry, Will you please explain your issue so I can help you.

      1. Larry says

        I apologize. That was the result of trying to follow more than one guide. I now have it running. Thank you for your up to date guide.

  3. sr9yar says

    Thanks for the heads up!

    One thing though . I was only able to logout with:
    JWTAuth::parseToken()->invalidate();
    Laravel 5.3