Beginning JWT in Laravel

Last Updated: August 24, 2019

Intsall the followoing package in your Laravel project

First you can install the third-party JWT package by running the following command in your terminal

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

Open config/app.php and add the following provider to the providers array:

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

],
 
'aliases' => [
 ....
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
 ]

Use the following command to publish JWT provider

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

Now you can use following command to generate token

 php artisan jwt:secret
jwt-auth secret [ZtlET4OzYVigiDmFly1OcXiiKbBvnlYCLz00sfmuMfi7mRkdgtzRLpGUKq3pfsP5] set successfully.

Now you can create the User model. Simply edit the code loacted at App\User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
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',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function getJWTIdentifier()
        {
            return $this->getKey();
        }
        public function getJWTCustomClaims()
        {
            return [];
        }
}

Create the Middleware

Now you can create the Middleware to filter the request comming to our API
If you are not familier with Laravel Middleware you can follow this tutorial

Create Controllers

You can create two Controlls in this exaple. One is to acesss the User model and other is to acess the data in your project

 php artisan make:controller UserController 
 php artisan make:controller DataControll

UserController class will have three methods
register()
This method will create new user in system by passing the email and password parameter

login()
This method can be used to authenticate the user by passing email and password. Once authentication is done you can get the token

getAuthenticatedUser()
You can use this method to get the authenticated user details by passing the token

Here is the full code of the UserController

<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

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

        try {
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 400);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        return response()->json(compact('token'));
    }

    public function register(Request $request)
    {
            $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);

        if($validator->fails()){
                return response()->json($validator->errors()->toJson(), 400);
        }

        $user = User::create([
            'name' => $request->get('name'),
            'email' => $request->get('email'),
            'password' => Hash::make($request->get('password')),
        ]);

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

        return response()->json(compact('user','token'),201);
    }


    public function getAuthenticatedUser()
        {
                try {

                        if (! $user = JWTAuth::parseToken()->authenticate()) {
                                return response()->json(['user_not_found'], 404);
                        }

                } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {

                        return response()->json(['token_expired'], $e->getStatusCode());

                } catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {

                        return response()->json(['token_invalid'], $e->getStatusCode());

                } catch (Tymon\JWTAuth\Exceptions\JWTException $e) {

                        return response()->json(['token_absent'], $e->getStatusCode());

                }

                return response()->json(compact('user'));
        }
}

Now we will add two methods to DataController class
I am going to add two methods to this class called open() and closed(). open() method can be accessed without authenticating the user and close() method is only for authenticated users

Now you can test on POSTMAN