Giter Site home page Giter Site logo

adhocore / php-jwt Goto Github PK

View Code? Open in Web Editor NEW
283.0 10.0 21.0 100 KB

Ultra lightweight, dependency free and standalone JSON web token (JWT) library for PHP5.6 to PHP8.2. This library makes JWT a cheese. It is a minimal JWT integration for PHP.

Home Page: https://github.com/adhocore/php-jwt

License: MIT License

PHP 100.00%
php7 php-jwt json-web-token api-auth jwt jwt-auth jwt-authentication api-security oauth2 json-web-token-php json-web-signature adhocore php8 php

php-jwt's Introduction

adhocore/jwt

If you are new to JWT or want to refresh your familiarity with it, please check jwt.io

Latest Version Build Scrutinizer CI Codecov branch StyleCI Software License Tweet Support

  • Lightweight JSON Web Token (JWT) library for PHP7, PHP8 and beyond.
  • Zero dependency (no vendor bloat).
  • If you still use PHP5.6, use version 0.1.2

Installation

# PHP7.x, PHP8.x
composer require adhocore/jwt

# PHP5.6 (deprecated)
composer require adhocore/jwt:0.1.2

# For PHP5.4-5.5 (deprecated), use version 0.1.2 with a polyfill for https://php.net/hash_equals

Features

  • Six algorithms supported:
'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512'
  • kid support.
  • Leeway support 0-120 seconds.
  • Timestamp spoofing for tests.
  • Passphrase support for RS* algos.

Usage

use Ahc\Jwt\JWT;

// Instantiate with key, algo, maxAge and leeway.
$jwt = new JWT('secret', 'HS256', 3600, 10);

Only the key is required. Defaults will be used for the rest:

$jwt = new JWT('secret');
// algo = HS256, maxAge = 3600, leeway = 0

For RS* algo, the key should be either a resource like below:

$key = openssl_pkey_new([
    'digest_alg' => 'sha256',
    'private_key_bits' => 1024,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);

OR, a string with full path to the RSA private key like below:

$key = '/path/to/rsa.key';

// Then, instantiate JWT with this key and RS* as algo:
$jwt = new JWT($key, 'RS384');

Pro You dont need to specify pub key path, that is deduced from priv key.

Generate JWT token from payload array:

$token = $jwt->encode([
    'uid'    => 1,
    'aud'    => 'http://site.com',
    'scopes' => ['user'],
    'iss'    => 'http://api.mysite.com',
]);

Retrieve the payload array:

$payload = $jwt->decode($token);

Oneliner:

$token   = (new JWT('topSecret', 'HS512', 1800))->encode(['uid' => 1, 'scopes' => ['user']]);
$payload = (new JWT('topSecret', 'HS512', 1800))->decode($token);

Pro

Can pass extra headers into encode() with second parameter:

$token = $jwt->encode($payload, ['hdr' => 'hdr_value']);

Test mocking

Spoof time() for testing token expiry:

$jwt->setTestTimestamp(time() + 10000);

// Throws Exception.
$jwt->parse($token);

Call again without parameter to stop spoofing time():

$jwt->setTestTimestamp();

Examples with kid

$jwt = new JWT(['key1' => 'secret1', 'key2' => 'secret2']);

// Use key2
$token = $jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key2']);

$payload = $jwt->decode($token);

$token = $jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key3']);
// -> Exception with message Unknown key ID key3

Stabillity

The library is now marked at version 1.*.* as being stable in functionality and API.

Integration

Phalcon

Check adhocore/phalcon-ext.

Consideration

Be aware of some security related considerations as outlined here which can be valid for any JWT implementations.

php-jwt's People

Contributors

adhocore avatar bolner avatar dependabot-preview[bot] avatar jorisvanw avatar magnetik avatar peter279k avatar stoyan0v avatar stylecibot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-jwt's Issues

nbf validation issue

Hi, in the current version:

['nbf', $this->maxAge - $this->leeway, static::ERROR_TOKEN_NOT_NOW, 'Not now'],

That line should be:

['nbf', -$this->leeway, static::ERROR_TOKEN_NOT_NOW, 'Not now'],

When checking the nbf ("not before") time, then the "max age" value is not relevant.

Let's see an example:

  • Current time = 2020-10-08 12:00:00
  • Max age = 3 hours = 10800 sec
  • nbf = 2020-10-08 11:00:00 (will be valid after this time)
  • leeway = 5 sec (allow max 5 sec misalignment of server clocks)

Then the current code would say:

  • The token fails the nbf check because:
    • reference value = 2020-10-08 11:00:00 + 3 hours - 5 sec = 2020-10-08 13:59:55
    • And the current time still hasn't reached this value yet.

But it should only subtract the leeway, and leave the irrelevant "max age" out of this:

  • The nbf check is successful, because:
    • reference value = 2020-10-08 11:00:00 - 5 sec = 2020-10-08 10:59:55
    • And the current time is greater than this value.

new JWT() - 500 Internal server error

Hello, when I call the route with $jwt = new JWT('secret', 'HS256', 3600, 10); on code, returns Server Error 500, I'm using Docker:

api/test.php:

<?php
  include "../vendor/autoload.php";
	use Ahc\Jwt\JWT;

  $jwt = new JWT('secret', 'HS256', 3600, 10);
?>

Error on POST:
image

In Try Catch return this error:

Error Object
(
    [message:protected] => Class 'Ahc\Jwt\JWT' not found
    [string:Error:private] => 
    [code:protected] => 0
    [file:protected] => /var/www/html/api/test.php
    [line:protected] => 8
    [trace:Error:private] => Array
        (
        )

    [previous:Error:private] => 
)

When I remove $jwt = new JWT('secret', 'HS256', 3600, 10); the error not occurred.
Any idea how solve this?

Unsupported algo PS256

An uncaught Exception was encountered

Type: Ahc\Jwt\JWTException

Message: Unsupported algo PS256

Pass key as string?

From what I can see in docs, it seems only possible to pass a file path in the constructor. It would be helpful if I could pass the key directly as a string without having to create a file first (in my case it's coming from a database). Is there maybe a trick using the resource method somehow?

Move to GitHub action

Move to GitHub action.
Build should run on all php versions currently supported by this library.

validate with public key

Hi,

I managed to include this very user friendly library in a project and create a token that validates on jwt.io.
I am sending this token in a http header to another server where it needs to be validated. This is not working though. The other server only has access to the public key. When I try to echo (new JWT($public_key))->decode($token); I receive an error:

Uncaught Ahc\Jwt\JWTException: Invalid token: Signature failed in JWT.php:153 Stack trace: #0 ....Ahc\Jwt\JWT->decode(Array) #1 {main} thrown in JWT.php on line 153

Surely I am doing something wrong. How can I validate the JWT string and decode it to retrieve its content?

problem with PEM file key

I created a PEM file on server ubuntu 18 with openssl 1.1.1 using this code

 $privkey = openssl_pkey_new([
            'digest_alg' => 'sha256',
            'private_key_bits' => 1024,
            'private_key_type' => OPENSSL_KEYTYPE_RSA,
        ]);
        try {
            openssl_pkey_export_to_file($privkey, 'WEB-INF/config/' . $filename);
        } catch (Exception $e) {
            echo 'Caught exception: ',  $e->getMessage(), "\n";
        }

on the same server it runs well, encoding and decoding as expected.

Then if I try the to decode using the same PEM file on different server (wich use openssl 1.1.1f) it doesn't run saying that signature is invalid.

Doing the same using a string instead of PEM file works. I cannot understand... could it be that PEM file I created depend on specficia server?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.