JWT auth for Laravel and Lumen

Overview

JWT Artisan

Build Status

Token auth for Laravel and Lumen web artisans

JWT is a great solution for authenticating API requests between various services. This package makes working with JWT super easy for both Laravel and Lumen.

Why JWT?

Because you have

microservices

That need to authenticate with each other so you can turn away bad requests like

how bout no

Which is why JWT makes you feel like

yea baby

Contents

Setup

Install the package using composer

$ composer require generationtux/jwt-artisan

Add the appropriate service provider for Laravel/Lumen

// Laravel
// config/app.php
'providers' => [
    ...
    GenTux\Jwt\Support\LaravelServiceProvider::class,
]

// Lumen
// bootstrap/app.php
$app->register(GenTux\Jwt\Support\LumenServiceProvider::class);

Configure

All configuration for this package can be set using environment variables. The reason for using environment variables instead of config files is so that it can be integrated with both Laravel & Lumen as easily as possible. See the table below for the available config options and their defaults.

Config Default Description
JWT_SECRET null The secret key that will be used for sigining/validating tokens.
JWT_ALGO HS256 The algorithm to use for sigining tokens.
JWT_LEEWAY 0 Seconds of leeway for validating timestamps to account for time differences between systems
JWT_INPUT token By default we will look for the token in the Authorization header. If it's not found there, then this value will be used to search the sent input from the request to find the token.
JWT_HEADER Authorization By default the Authorization header key is used. This can be overridden with this value.

If you're using the JwtExceptionHandler to handle exceptions, these environment variables can be set to customize the error messages. (see below for information on using the exception handler)

Config Default Description
JWT_MESSAGE_ERROR There was an error while validating the authorization token. 500 A general error occured while working with the token.
JWT_MESSAGE_INVALID Authorization token is not valid. 401 The provided token is invalid in some way: expired, mismatched signature, etc.
JWT_MESSAGE_NOTOKEN Authorization token is required. 401 There was no token found with the request.
JWT_MESSAGE_NOSECRET No JWT secret defined. 500 Unable to find the JWT secret for validating/signing tokens.

Working with Tokens

Creating Tokens

Inject an instance of GenTux\Jwt\JwtToken into your controller or other service to create new tokens.



use GenTux\Jwt\JwtToken;

class TokensController extends controller
{
    public function create(JwtToken $jwt)
    {
        $payload = ['exp' => time() + 7200]; // expire in 2 hours
        $token = $jwt->createToken($payload); // new instance of JwtToken

        return (string) $token;
    }
}

Implement GenTux\Jwt\JwtPayloadInterface to pass other objects to createToken for a more dynamic payload.



use GenTux\Jwt\JwtPayloadInterface;

class User extends Model implements JwtPayloadInterface
{
    public function getPayload()
    {
        return [
            'sub' => $this->id,
            'exp' => time() + 7200,
            'context' => [
                'email' => $this->email
            ]
        ];
    }
}

Then simply pass that object when creating the token



use GenTux\Jwt\JwtToken;

class TokensController extends controller
{
    public function create(JwtToken $jwt)
    {
        $user = User::find(1);
        $token = $jwt->createToken($user);

        return $token->payload(); // ['sub' => 1, exp => '...', 'context' => ...]
    }
}

You can set a specific secret and algorithm to use if necessary

public function create(JwtToken $jwt)
{
    return $jwt
            ->setSecret('secret_123')
            ->setAlgorithm('custom')
            ->createToken('[...]');
}

Validating Tokens

The easiest way to validate a request with a JWT token is to use the provided middleware.



// Laravel
Route::group(['middleware' => 'jwt'], function() {
    Route::post('/foo', 'FooController');
});

// Lumen
$app->group(['middleware' => 'jwt', 'namespace' => 'App\Http\Controllers'], function($app)  {
    $app->post('/foo', 'FooController');
});

When a token is invalid, GenTux\Jwt\Exceptions\InvalidTokenException will be thrown. If no token is provided, then GenTux\Jwt\Exceptions\NoTokenException will be thrown.

To manually validate the token, you can get tokens in any class using the trait GenTux\Jwt\GetsJwtToken.

For example, in a Laravel request object



use GenTux\Jwt\GetsJwtToken;

class CreateUser extends FormRequest
{
    use GetsJwtToken;

    public function authorize()
    {
        return $this->jwtToken()->validate();
    }
}

Or in a controller for Lumen



use GenTux\Jwt\GetsJwtController;

class FooController extends controller
{
    use GetsJwtToken;

    public function store()
    {
        if( ! $this->jwtToken()->validate()) {
            return redirect('/nope');
        }

        ...
    }
}

Payloads

Once you have the token, working with the payload is easy.



use GenTux\Jwt\GetsJwtToken;

class TokenService
{

    use GetsJwtToken;

    public function getExpires()
    {
        $payload = $this->jwtPayload(); // shortcut for $this->jwtToken()->payload()

        return $payload['exp'];
    }
}

The payload method for JwtToken accepts a path that can be used to get specific data from the payload.



use GenTux\Jwt\GetsJwtToken;

class TokenService
{
    use GetsJwtToken;

    public function getData()
    {
        // ['exp' => '123', 'context' => ['foo' => 'bar']]

        $token = $this->jwtToken();
        $token->payload('exp'); // 123
        $token->payload('context.foo'); // bar
        $token->payload('context.baz'); // null
    }
}

Handling Errors

This package can handle JWT exceptions out of the box if you would like. It will take all JWT exceptions and return JSON error responses. If you would like to implements your own error handling, you can look at GenTux\Jwt\Exceptions\JwtExceptionHandler for an example.

To implement, add the following inside of app/Exceptions/Handler.php



use GenTux\Jwt\Exceptions\JwtException;
use GenTux\Jwt\Exceptions\JwtExceptionHandler;

class Handler extends ExceptionHandler
{
    use JwtExceptionHandler;

    public function render($request, Exception $e)
    {
        if($e instanceof JwtException) return $this->handleJwtException($e);

        ...
    }
}
Comments
  • Blank token

    Blank token

    Hello,

    I am trying to generate a token once a user/pass is validated on my Lumen setup, but the generated token is blank.

    I have modified my controller like this:

    ` use GenTux\Jwt\JwtToken; use GenTux\Jwt\Drivers\FirebaseDriver; use GenTux\Jwt\GetsJwtToken;

    class LoginController extends Controller { use GetsJwtToken; ...

    public function login(Request $request,JwtToken $jwt)
    {
    

    ... $payload = ['exp' => time() + 7200]; // expire in 2 hours //$jwt = new JwtToken(new FirebaseDriver()); $token = $jwt->createToken($payload); // new instance of JwtToken

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

    } `

    I also tried to create the $jwt object directly but that did not work either. Then env variables are setup as well as the app.php registration. Why is the token blank? On your example the JwtToken $jwt is passed to the controller, can you explain where the token is set? Thank you.

    opened by hugoalvarado 4
  • Error with token creation

    Error with token creation

    It's throwing below error,

    {"error":true,"code":400,"message":"Argument 2 passed to App\Http\Controllers\LoginController::generateToken() must be an instance of GenTux\Jwt\JwtToken, none given, called in /home/krds/Documents/www/projects/krds/api/app/Http/Controllers/LoginController.php on line 55 and defined"}

    `public function generateToken($id, JwtToken $jwt) { $payload = ['exp' => time() + 86400, 'sub' => $id]; // expire in 24 hours $token = $jwt->createToken($payload); // new instance of JwtToken

        return (string) $token;
    }`
    
    opened by code4hub 3
  • How use Middleware In Laravel  5.6

    How use Middleware In Laravel 5.6

    I detect one bug with Laravel 5.6.* You can create Tokens well and retrieve the payload information with GetJwtToken, but when you implements Middleware validation always throw "Class jwt does not exist" because LaravelServiceProvider cant add the middleware, my solution was:

    Modify app/Http/Kernel.php and add the middleware manually

    
    protected $routeMiddleware = [
    ...
    'jwt' => \GenTux\Jwt\Http\JwtMiddleware::class
    ]
    
    

    Then you can use the middleware in your routes and no more error "Class jwt does not exist"

    Route::get('/sample', 'SampleController@generate');
    Route::get('/sample', 'SampleController@check')->middleware("jwt");
    

    or

    Route::get('/sample', 'SampleController@generate');
    Route::middleware(['jwt'])->group(function () {
    Route::get('/sample', 'SampleController@check');
    });
    

    I try to change the signature LaravelServiceProvider::registerMiddleware to LaravelServiceProvider::register but throws the same error 😢 (I never create Laravel Providers 😂, I dont know if app['router'] exists on Laravel 5.6.* )

    opened by kiramishima 2
  • JWT Expired token handler

    JWT Expired token handler

    I was wondering why the exception handler doesn't account for expired tokens? It seems to cover invalid and missing tokens but for some reason I had to register an additional handler in lumen to catch an instance of Firebase JWT expired token exception and output my own JSON error response. Maybe there is a better way to do this?

    opened by ryanscherler 2
  • Wrong number of segments error

    Wrong number of segments error

    Hey guys,

    First off, thanks for making this package. It's been a nice addition to my stack. That being said, I do occasionally get an error with the following stack trace.

    lumen.ERROR: UnexpectedValueException: Wrong number of segments in /var/www/html/shipping/vendor/firebase/php-jwt/src/JWT.php:67 Stack trace: #0 /var/www/html/shipping/vendor/generationtux/jwt-artisan/src/Drivers/FirebaseDriver.php(64): Firebase\JWT\JWT::decode('Error', 'sp85twcodSCl8CR...', Array) #1 /var/www/html/shipping/vendor/generationtux/jwt-artisan/src/JwtToken.php(180): GenTux\Jwt\Drivers\FirebaseDriver->decodeToken('Error', 'sp85twcodSCl8CR...', 'HS256') #2 /var/www/html/shipping/vendor/generationtux/jwt-artisan/src/GetsJwtToken.php(72): GenTux\Jwt\JwtToken->payload(NULL) #3 /var/www/html/shipping/app/Http/Controllers/Controller.php(19): App\Http\Controllers\Controller->jwtPayload()

    In my base controller class's constructor I'm simply calling

    $payload = $this->jwtPayload()

    when the error occurs.

    opened by adamkelso 2
  • How to refresh token?

    How to refresh token?

    Thanks a ton for creating this package.

    I am using this package in my mobile app to authenticate user. I don't want user to logout after X min and ask them to re-login.

    Is there any way that i can refresh the token, if given token is about to expires or expired?

    opened by kalpitpandit 2
  • Can no longer use response()->json() in error handling

    Can no longer use response()->json() in error handling

    Laravel Framework version Lumen (5.2.6) (Laravel Components 5.2.*)

    As per Lumen's documentation, I have defined my own error handling behaviour in app/Exceptions/Handler.php;

    public function render($request, Exception $e)
    {
        if ($e instanceof ValidationException)
            return parent::render ($request, $e);
    
        $obj = [
            'error' => true,
            'message' => $e->getMessage ()
        ];
    
        if (env ('APP_DEBUG', false))
        {
            $obj['file'] = $e->getFile ();
            $obj['line'] = $e->getLine ();
            $obj['trace'] = $e->getTrace ();
        }
    
        return response ()->json ($obj);
    }
    

    As you can see, I use response ()->json () to return a response in JSON format. However, any time an error occurs, the JWT library interferes and causes another exception to be thrown, causing that one to be reported back to the client instead of the original exception. screenshot from 2016-05-06 13-43-59

    opened by RobinJ1995 2
  • Middleware Usage

    Middleware Usage

    Hello Friend,

    Sorry for a question so simple, I'm trying to understand how to use your code with the middleware of the lumen, but I do not understand how to work the service provider. Authentication provider user [api] is not defined.

    Can you help me indicating some document or way for me to solve this problem?

    Thank you

    opened by sr2ds 2
  • Ethanknowlton3819/sc 36782/open source use GitHub actions for php packages

    Ethanknowlton3819/sc 36782/open source use GitHub actions for php packages

    • Removed Travis CI
    • Setup Tests with Github Actions
    • Supports testing multiple PHP versions if we wish to do so
    • Test workflow runs on pull request open, edited, or review requested
    opened by eknowlton 1
  • Bump symfony/http-kernel from 5.1.2 to 5.1.5

    Bump symfony/http-kernel from 5.1.2 to 5.1.5

    Bumps symfony/http-kernel from 5.1.2 to 5.1.5.

    Release notes

    Sourced from symfony/http-kernel's releases.

    v5.1.5

    Changelog (https://github.com/symfony/http-kernel/compare/v5.1.4...v5.1.5)

    • no changes

    v5.1.4

    Changelog (https://github.com/symfony/http-kernel/compare/v5.1.3...v5.1.4)

    • bug #37841 Backport handler lock when using VAR_DUMPER_FORMAT (ogizanagi)

    v5.1.3

    Changelog (https://github.com/symfony/http-kernel/compare/v5.1.2...v5.1.3)

    • bug #37341 Fix support for PHP8 union types (nicolas-grekas)
    Commits
    • 3e32676 Update VERSION for 5.1.5
    • f855601 Merge branch '4.4' into 5.1
    • cdf1e9b security #cve-2020-15094 Remove headers with internal meaning from HttpClient...
    • 8e8d0ed Remove headers with internal meaning from HttpClient responses
    • 05293dd Bump Symfony version to 5.1.5
    • f829c24 Update VERSION for 5.1.4
    • a5ed890 Bump Symfony version to 4.4.13
    • f93f6b3 Update VERSION for 4.4.12
    • 794f3d4 Merge branch '4.4' into 5.1
    • 98fb210 minor #37831 stop using deprecated PHPUnit APIs (xabbuh)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Problem on token validation

    Problem on token validation

    I am trying to validate the token for test purposes I am using Postman and set the header Authorization : Bearer xxxxxxxxx

    but still I get the error

    NoTokenException in GetsJwtToken.php line 51:
    JWT token is required.
    
    opened by nmfarshad 1
Releases(v1.1.0)
Owner
⑅ Generation Tux ⑅
⑅ Generation Tux ⑅
Laravel Auth guard for FusionAuth JWT

Laravel FusionAuth JWT Implement an Auth guard for FusionAuth JWTs in Laravel. It ships with also a middleware to check against the user role. Install

Theraloss 7 Feb 21, 2022
Simple JWT Auth support for Laravel PHP Framework

Laravel JWT Simple JWT Auth for Laravel PHP Framework using Firebase JWT under the hood. Installation Standard Composer package installation: composer

Ricardo Čerljenko 34 Nov 21, 2022
Multi Auth and admin auth in Laravel Project

Laravel Multi Auth For Complete Documentation, visit Here This package is just create admin side (multi auth), which is totaly isolated from your norm

Bitfumes 435 Dec 31, 2022
A Native PHP MVC With Auth. If you will build your own PHP project in MVC with router and Auth, you can clone this ready to use MVC pattern repo.

If you will build your own PHP project in MVC with router and Auth, you can clone this ready to use MVC pattern repo. Auth system is implemented. Works with bootstrap 5. Composer with autoload are implemented too for future composer require.

null 2 Jun 6, 2022
CakeDC Auth Objects is a refactor of the existing Auth objects present in the CakeDC Users Plugin, to let anyone else use them in their projects.

CakeDC Auth Objects is a refactor of the existing Auth objects present in the CakeDC Users Plugin, to let anyone else use them in their projects.

Cake Development Corporation 24 Sep 23, 2022
HTTP Basic Auth Guard for Lumen 5.x

HTTP Basic Auth Guard HTTP Basic Auth Guard is a Lumen Package that lets you use basic as your driver for the authentication guard in your application

Christopher Lass 40 Nov 11, 2022
PSR-7 and PSR-15 JWT Authentication Middleware

PSR-7 and PSR-15 JWT Authentication Middleware This middleware implements JSON Web Token Authentication. It was originally developed for Slim but can

Mika Tuupola 782 Dec 18, 2022
Probando JWT en Laravel

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

SelsiusRC28 1 Nov 2, 2021
Laravel JWT-Authentication API starter kit for rapid backend prototyping.

Laravel JWT API A Laravel JWT API starter kit. Features Laravel 8 Login, register, email verification and password reset Authentication with JWT Socia

Oybek Odilov 3 Nov 6, 2022
Security Defense for Firebase's PHP-JWT Library

PHP-JWT-Guard Protect your code from being impacted by issue 351 in firebase/php-jwt. Installation First, install this library with Composer: composer

Paragon Initiative Enterprises 8 Nov 27, 2022
Rest API - JWT - Symfony5

Symfony5 JWT - REST API Example Symfony5 JWT - REST API Example Built With PHP Symfony 5 PostgreSQL Getting Started This is an example of how you may

Salih Gencer 1 Dec 24, 2021
PHP package for JWT

PHP-JWT A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to RFC 7519. Installation Use composer to manage your dependenc

Firebase 8.6k Jan 7, 2023
Single file PHP that can serve as a JWT based authentication provider to the PHP-CRUD-API project

Single file PHP that can serve as a JWT based authentication provider to the PHP-CRUD-API project

Maurits van der Schee 163 Dec 18, 2022
JSON Web Token (JWT) for webman plugin

JSON Web Token (JWT) for webman plugin Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。

 ShaoBo Wan(無尘) 25 Dec 30, 2022
Sistema de Administrativo - Cliente e Vendedor - Autenticação JWT e Relacionamentos BD

Hi there, My name is ATTILA SAMUELL TABORY, I love technology ?? Sistema Administrativo Laravel e Vue JS - JWT e Relacionamentos BD Sistema Administra

Attila Samuell 7 May 9, 2022
Aplicação criada com Slim Framework com objetivo de criar autenticação com JWT e aprender sobre o framework Slim

Slim JWT App Essa aplicação tem como foco o aprendizado do Framework Slim e também a utilização de JWT. Como rodar a Aplicação A aplicação está config

Nicolas Pereira 9 Oct 4, 2022
JWT Authenticator for symfony

HalloVerdenJwtAuthenticatorBundle This bundle provides a JWT authenticator for Symfony applications. It's using PHP JWT Framework for parsing and vali

Hallo Verden 0 Jul 8, 2022
Laravel Auth is a Complete Build of Laravel 8 with Email Registration Verification, Social Authentication, User Roles and Permissions, User Profiles, and Admin restricted user management system.

Laravel Auth is a Complete Build of Laravel 8 with Email Registration Verification, Social Authentication, User Roles and Permissions, User Profiles, and Admin restricted user management system. Built on Bootstrap 4.

Jeremy Kenedy 2.8k Dec 31, 2022
Files Course Laravel Micro Auth and Authorization

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

EspecializaTi 8 Oct 22, 2022