Restful API In Laravel 5.5 Using jwt Authentication

Today, we are share with you how to built restful API in laravel using JWT(JSON Web Token). it is very eassy and simple implementation in laravel. when you work with larg application and you also want make mobile or android application for this project. you should be write API layer or API for your application which help communication with your android app and your live server.

In simple term in API is you pass some argument as a url GET request and POST request from app and server first check this API url is valid or not and then send some output data in json formate and android or mobile application develoer manage it.

In laravel you want to buitl API then JWT(JSON Web Token) is best for it and easy to use. and it also good for apply security on your RESTful API

Simple follow this step and integrate JWT(JSON Web Token) in your laravel application. You are also manage multi authentiication with JWT(JSON Web Token) check this link JWT(JSON Web Token) multi authentication

Step : 1 Install tymon/jwt-auth package in your laravel application

First we need to install tymon/jwt-auth in our laravel application using following command


composer require tymon/jwt-auth

after intallation tymon/jwt-auth package in your laravel application, then config it like tha..

Step : 2 Make some changes in config/app.php file

Now open your config/app.php file and set service provider and their aliase.


'providers' => [
	....
	Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
],
'aliases' => [
	....
	'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
],

Step : 3 Generate configuration file

After this completion then after publish configuration file using following command.


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

After run this command then config/jwt.php file generated automatic. and it look like this. if you want some custom configer in it you should make in this file.


/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

return [

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Secret
    |--------------------------------------------------------------------------
    |
    | Don't forget to set this, as it will be used to sign your tokens.
    | A helper command is provided for this: `php artisan jwt:generate`
    |
    */

    'secret' => env('JWT_SECRET', 'obOoFDiAihNZE6kPtX6WQXOErPvuY3Oe'),

    /*
    |--------------------------------------------------------------------------
    | JWT time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token will be valid for.
    | Defaults to 1 hour
    |
    */

    'ttl' => 600,

    /*
    |--------------------------------------------------------------------------
    | Refresh time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token can be refreshed
    | within. I.E. The user can refresh their token within a 2 week window of
    | the original token being created until they must re-authenticate.
    | Defaults to 2 weeks
    |
    */

    'refresh_ttl' => 20160,

    /*
    |--------------------------------------------------------------------------
    | JWT hashing algorithm
    |--------------------------------------------------------------------------
    |
    | Specify the hashing algorithm that will be used to sign the token.
    |
    | See here: https://github.com/namshi/jose/tree/2.2.0/src/Namshi/JOSE/Signer
    | for possible values
    |
    */

    'algo' => 'HS256',

    /*
    |--------------------------------------------------------------------------
    | User Model namespace
    |--------------------------------------------------------------------------
    |
    | Specify the full namespace to your User model.
    | e.g. 'Acme\Entities\User'
    |
    */

    'user' => 'App\User',

    /*
    |--------------------------------------------------------------------------
    | User identifier
    |--------------------------------------------------------------------------
    |
    | Specify a unique property of the user that will be added as the 'sub'
    | claim of the token payload.
    |
    */

    'identifier' => 'id',

    /*
    |--------------------------------------------------------------------------
    | Required Claims
    |--------------------------------------------------------------------------
    |
    | Specify the required claims that must exist in any token.
    | A TokenInvalidException will be thrown if any of these claims are not
    | present in the payload.
    |
    */

    'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'],

    /*
    |--------------------------------------------------------------------------
    | Blacklist Enabled
    |--------------------------------------------------------------------------
    |
    | In order to invalidate tokens, you must have the blacklist enabled.
    | If you do not want or need this functionality, then set this to false.
    |
    */

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    |--------------------------------------------------------------------------
    | Providers
    |--------------------------------------------------------------------------
    |
    | Specify the various providers used throughout the package.
    |
    */

    'providers' => [

        /*
        |--------------------------------------------------------------------------
        | User Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to find the user based
        | on the subject claim
        |
        */

        'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter',

        /*
        |--------------------------------------------------------------------------
        | JWT Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to create and decode the tokens.
        |
        */

        'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter',

        /*
        |--------------------------------------------------------------------------
        | Authentication Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to authenticate users.
        |
        */

        'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter',

        /*
        |--------------------------------------------------------------------------
        | Storage Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to store tokens in the blacklist
        |
        */

        'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter',

    ],

];

Bydefault User model use for authentication but if you want use another model for authentication you can change it. You are also manage multi authentiication with JWT(JSON Web Token) check this link JWT(JSON Web Token) multi authentication

Step : 4 Generate JWT Token

Now for token encryption, I need to generate a secret key by running following line of code usign following command

For laravel 5.4 or downgrade version

 
php artisan jwt:generate

For laravel 5.5

 
php artisan jwt:secret

Following Error Only Generate In Laravel 5.5

If you run above command and you face following Error message in terminal. generally this error accur in laravel5.5 version. we have also solution for it.

[ReflectionException]
Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist

Solution

Please, install new dev version of tymon/jwt-auth package. this issue resolve in dev package development. so, again run following command for install dev version package.


composer require tymon/jwt-auth:dev-develop --prefer-source

After install dev version package open your config/app.php file and replace old service provider to new like that.


'providers' => [
    ....
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class to Tymon\JWTAuth\Providers\LaravelServiceProvider::class
],
 

After replace service provider then now run following command for generate jwt key

 
php artisan jwt:secret

Step : 5 Create middleware for JWT

Now we are create middleware for JWT. open your app/Http/Middleware folder and create one authJWT.php file and put into it followign code.


namespace App\Http\Middleware;

use Closure;
use JWTAuth;
use Exception;

class authJWT
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        try {
            $user = JWTAuth::toUser($request->input('token'));
        } catch (Exception $e) {
            if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
                return response()->json(['error'=>'Token is Invalid']);
            }else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
                return response()->json(['error'=>'Token is Expired']);
            }else{
                return response()->json(['error'=>'Something is wrong']);
            }
        }
        return $next($request);
    }
}

Step : 6 Register Middleware

We are create middleware for JWT now we are need to Register it. open your app/Http/Kernel.php file and make following changes


namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    ...
    ...
    protected $routeMiddleware = [
        ...
        'jwt-auth' => \App\Http\Middleware\authJWT::class,
    ];
}

Step : 7 Add following route in routes/api.php

Laravel provide routes/api.php file for write API route and this is best for manage all API route in it. so our web application route and API route not mix.

Look at in bellow route you can see i use two middleware "api" and "cors". cors is not mandatory, but Sometime you make API and call it then you get the following error message so we are create those two middleware for avoide this error

"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://test.com/api/register. (Reason: CORS header 'Access-Control-Allow-Origin' missing)."

You also found how to create this middleware open this link Ajax - Cross-Origin Request Blocked in Larave 5?.

 


Route::group(['middleware' => ['api','cors']], function () {
    Route::post('auth/login', 'ApiController@login');
    Route::group(['middleware' => 'jwt.auth'], function () {
        Route::get('user', 'ApiController@getAuthUser');
    });
});

Step : 8 Create Controller

Now we are create controller, so create ApiController.php file in your app/Http/Controllers folder.


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use JWTAuth;
use JWTAuthException;
use App\User;

class ApiController extends Controller
{

    public function __construct()
    {
        $this->user = new User;
    }
    
    public function login(Request $request){
        $credentials = $request->only('email', 'password');
        $token = null;
        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json([
                    'response' => 'error',
                    'message' => 'invalid_email_or_password',
                ]);
            }
        } catch (JWTAuthException $e) {
            return response()->json([
                'response' => 'error',
                'message' => 'failed_to_create_token',
            ]);
        }
        return response()->json([
            'response' => 'success',
            'result' => [
                'token' => $token,
            ],
        ]);
    }

    public function getAuthUser(Request $request){
        $user = JWTAuth::toUser($request->token);        
        return response()->json(['result' => $user]);
    }

}

Step : 9 Test With Postman

You can test your API with postman and another API testing tool

Now we are ready to run our example so run bellow command ro quick run:

php artisan serve

Now you can open bellow URL on your browser:

http://localhost:8000

If you want to any problem then please write comment and also suggest for new topic for make tutorials in future. Thanks...

 Prev post

Next post