Git Product home page Git Product logo

reallysimplejwt's Introduction

Really Simple JSON Web Tokens

Actions Status codecov Infection MSI StyleCI Latest Stable Version Packagist PHP Version Support Total Downloads

A simple PHP library for creating JSON Web Tokens that uses HMAC SHA256 to sign signatures. For basic usage the library exposes a static interface to allow developers to create a token that stores a user identifier and expiration time.

The library is also open to extension, developers can define their own encoding and secret standards, set all the RFC standard JWT claims, and set their own private claims.

You can easily integrate ReallySimpleJWT with PSR-7 / PSR-15 compliant frameworks such as Slim PHP with the PSR-JWT middleware library. Please read the framework integration documentation to learn more.

If you need to read tokens in the browser please take a look at our JavaScript / Typescript library RS-JWT.

Contents

What is a JSON Web Token?

JSON Web Tokens is a standard for creating URL friendly access tokens that assert claims about a user or system.

A token is broken down into three parts; the header, the payload and the signature; with each part separated by a dot. Each part is encoded using the base64URL standard, see the RFC.

An example JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The header and payload are both encoded JSON strings that contain a number of claims:

// Example Header
{
  "alg": "HS256",
  "typ": "JWT"
}

// Example Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

A claim is a key value pair, eg "typ": "JWT", please read RFC 7519 to learn more about JSON Web Token claims.

Token security is achieved via the signature which is made up of the header, payload and a secret known only to the token author. This information is hashed and then base64URL encoded.

If a malicious user attempts to edit the header or payload claims they will be unable to replicate the signature so long as you use a strong secret. See Token Security for more information on this.

Setup

To install this package you will need to install Composer and then run composer init. Once this is done you can install the package via the command line or by editing the composer.json file created by the composer init command.

Finally you will need to reference the composer autoloader in your PHP code, require 'vendor/autoload.php';. The location of the autoload file will differ dependent on where your code is run and may not be required if you are using a framework.

Install via Composer on the command line:

composer require rbdwllr/reallysimplejwt

Install via the composer.json file:

Add the following to your composer.json file:

"require": {
    "rbdwllr/reallysimplejwt": "^5.0"
}

Then run:

composer update

Basic Usage

For basic usage the library exposes a set of static methods via the ReallySimpleJWT\Token class which allow a developer to create and validate basic JSON Web Tokens.

Create Token

Call the create() static method and pass in a user identifier, a secret, an expiration date time number and the token issuer.

This will return a token string on success and throw a ReallySimpleJWT\Exception\BuildException on failure.

use ReallySimpleJWT\Token;

$userId = 12;
$secret = 'sec!ReT423*&';
$expiration = time() + 3600;
$issuer = 'localhost';

$token = Token::create($userId, $secret, $expiration, $issuer);

To create a more customised token developers can use the customPayload() method. This allows the creation of a token based on an array of key value pairs which represent the payload claims.

use ReallySimpleJWT\Token;

$payload = [
    'iat' => time(),
    'uid' => 1,
    'exp' => time() + 10,
    'iss' => 'localhost'
];

$secret = 'Hello&MikeFooBar123';

$token = Token::customPayload($payload, $secret);

On success the customPayload() method will return a JWT token string and on failure it will throw an exception.

Validate Token

To validate a JSON web token call the validate() static method, pass in the token string and the secret. The validate method checks the token structure is correct and the signature is valid.

It will return true on success and false on failure.

use ReallySimpleJWT\Token;

$token = 'aaa.bbb.ccc';
$secret = 'sec!ReT423*&';

$result = Token::validate($token, $secret);

There are also methods available to validate the token's expiration claim and not before claim. Both will return true on success and false on failure.

use ReallySimpleJWT\Token;

$token = 'aaa.bbb.ccc';

Token::validateExpiration($token);

Token::validateNotBefore($token);

Get Header and Payload Claims Data

To retrieve the token claims data from the header or payload call the getHeader() and or getPayload() static methods.

Both methods will return an associative array on success and throw an exception on failure.

use ReallySimpleJWT\Token;

$token = 'aaa.bbb.ccc';

// Return the header claims
Token::getHeader($token);

// Return the payload claims
Token::getPayload($token);

Build, Parse and Validate Factory Methods

The ReallySimpleJWT\Token class also provides three factory methods to gain access to the core ReallySimpleJWT\Build, ReallySimpleJWT\Parse, and ReallySimpleJWT\Validate classes. These classes allow you to build custom tokens, and parse and validate tokens as you see fit.

Token::builder(); // Returns an instance of ReallySimpleJWT\Build

Token::parser($token); // Returns an instance of ReallySimpleJWT\Parse

Token::validator($token, $secret); // Returns an instance of ReallySimpleJWT\Validate

Non-Static Usage

The ReallySimpleJWT\Token class is just a wrapper for the ReallySimpleJWT\Tokens class which can be used directly for those who'd prefer to instantiate and inject the functionality.

use ReallySimpleJWT\Tokens;

$tokens = new Tokens();

$id = 52;
$secret = 'sec!ReT423*&';
$expiration = time() + 50;
$issuer = 'localhost';

$token = $tokens->create('id', $id, $secret, $expiration, $issuer);
$token->getToken();

Please note when calling the create() and customPayload() methods on the Tokens class they will return an instance of the Jwt class unlike the Token class which will return a token string.

In addition, the create() method has a slightly different signature to the Tokens class as a user identifier key must be passed in.

create(string $userKey, $userId, string $secret, int $expiration, string $issuer): Jwt

Advanced Usage

To create customised JSON Web Tokens developers need to access the ReallySimpleJWT\Build, ReallySimpleJWT\Parse and ReallySimpleJWT\Validate classes directly.

Create Custom Token

The ReallySimpleJWT\Build class allows you to create a completely unique JSON Web Token. It has helper methods for all the RFC defined header and payload claims. For example, the setIssuer() method will add the iss claim to the token payload.

The class also allows developers to set custom header and payload claims via the setHeaderClaim() and setPayloadClaim() methods.

The methods can be chained together and when the build() method is called the token will be generated and returned as a ReallySimpleJWT\Jwt object.

use ReallySimpleJWT\Build;
use ReallySimpleJWT\Helper\Validator;
use ReallySimpleJWT\Encoders\EncodeHS256;

$secret = '!secReT$123*';

$build = new Build('JWT', new Validator(), new EncodeHS256($secret));

$token = $build->setContentType('JWT')
    ->setHeaderClaim('info', 'foo')
    ->setIssuer('localhost')
    ->setSubject('admins')
    ->setAudience('https://google.com')
    ->setExpiration(time() + 30)
    ->setNotBefore(time() - 30)
    ->setIssuedAt(time())
    ->setJwtId('123ABC')
    ->setPayloadClaim('uid', 12)
    ->build();

Access the Token

A ReallySimpleJWT\Jwt object is returned when a developer calls the build() method on the ReallySimpleJWT\Build class. The Jwt class offers a single getToken() method which returns the token string.

To parse a JSON Web Token via the ReallySimpleJWT\Parse class a developer must first create a new ReallySimpleJWT\Jwt object by injecting the token string on instantiation. The Jwt class will validate the structure of the token on instantiation to ensure integrity.

use ReallySimpleJWT\Jwt;

$token = 'aaa.bbb.ccc';

$jwt = new Jwt($token);

// Return the token
$jwt->getToken();

Parse Token

The ReallySimpleJWT\Parse class allows a developer to parse a JWT and the parse() method will decode the JSON Web Token and return the result as a ReallySimpleJWT\Parsed object. This will provide access to the header and payload claims data the token holds.

use ReallySimpleJWT\Parse;
use ReallySimpleJWT\Jwt;
use ReallySimpleJWT\Decode;

$token = 'aaa.bbb.ccc';

$jwt = new Jwt($token);

$parse = new Parse($jwt, new Decode());

$parsed = $parse->parse();

// Return the token header claims as an associative array.
$parsed->getHeader();

// Return the token payload claims as an associative array.
$parsed->getPayload();

Access Token Claims Data

The ReallySimpleJWT\Parsed class is returned when a developer calls the parse() method on the ReallySimpleJWT\Parse class.

It provides a number of helper methods to gain access to the token claim data. A developer can call the getHeader() and getPayload() methods to gain access to the respective claim data as associative arrays.

Alternatively a developer can call one of the RFC compliant claim methods:

Header

  • getAlgorithm()
  • getType()
  • getContentType()

Payload

  • getIssuer()
  • getSubject()
  • getAudience()
  • getExpiration()
  • getNotBefore()
  • getIssuedAt()
  • getJwtId()
  • getExpiresIn()
  • getUsableIn()

Token Validation Methods

To Validate a JSON Web Token a developer can use the ReallySimpleJWT\Validate class. To use the validate class you need to create and inject a ReallySimpleJWT\Parsed object. This is so the validate class can access the information contained within the token.

use ReallySimpleJWT\Jwt;
use ReallySimpleJWT\Parse;
use ReallySimpleJWT\Validate;
use ReallySimpleJwt\Decode;
use ReallySimpleJwt\Encoders\EncodeHS256;
use ReallySimpleJwt\Helper\Validator;

$token = new Jwt('abc.def.ghi');

$parse = new Parse($jwt, new Decode());

$parsed = $parse->parse();

$validate = new Validate(
    $parsed,
    new EncodeHS256(),
    new Validator()
);

$validate->signature();

Six validation methods are available which can all be chained:

  • signature() confirms the token signature is valid.
  • expiration() confirms the token expiration claim (exp) has not expired.
  • notBefore() confirms the token not before claim (nbf) has elapsed.
  • audience() confirms the token audience claim (aud) matches what is expected.
  • algorithm() confirms the token algorithm claim (alg) matches what is expected and is valid (See: RFC 7518).
  • algorithmNotNone() confirms the token algorithm claim (alg) is not set to none.

Each validation method will throw a ReallySimpleJWT\Exception\ValidateException if there is anything wrong with the supplied token.

Custom Encoding

By default this library hashes and encodes the JWT signature via hash_hmac() using the sha256 algorithm. If a developer would like to use a customised form of encoding they just need to generate a custom encode class which complies with the ReallySimpleJWT\Interfaces\Encode interface. This can then be injected into the ReallySimpleJWT\Build and ReallySimpleJWT\Validate classes.

interface EncodeInterface
{
    public function getAlgorithm(): string;

    public function encode(string $toEncode): string;

    public function signature(string $header, string $payload): string;
}

Error Messages and Codes

The ReallySimpleJWT library will in a number of situations throw exceptions to highlight problems when creating, parsing and validating JWT tokens. The error codes, messages and their explanations are in the table below.

There are six exception types that may be thrown:

  • ReallySimpleJWT\Exception\BuildException
  • ReallySimpleJWT\Exception\EncodeException
  • ReallySimpleJWT\Exception\JwtException
  • ReallySimpleJWT\Exception\ParsedException
  • ReallySimpleJWT\Exception\TokensException
  • ReallySimpleJWT\Exception\ValidateException
Code Message Explanation
1 Token has an invalid structure. Token must have three parts separated by dots.
2 Audience claim does not contain provided StringOrURI. The aud claim must contain the provided string or URI string provided.
3 Signature is invalid. Signature does not match header / payload content. Could not replicate signature with provided header, payload and secret.
4 Expiration claim has expired. The exp claim must be a valid date time number in the future.
5 Not Before claim has not elapsed. The nbf claim must be a valid date time number in the past.
6 The header claim [claim] is not set. Attempt was made to access a header claim which does not exist.
7 The payload claim [claim] is not set. Attempt was made to access a payload claim which does not exist.
8 Invalid payload claim. Payload claims must be key value pairs of the format string: mixed.
9 Invalid secret. Must be 12 characters in length, contain upper and lower case letters, a number, and a special character *&!@%^#$
10 Algorithm claim is not valid. Algorithm should be a valid Digital Signature or MAC Algorithm, or none. See RFC 7518.
11 Algorithm claim should not be none. The alg claim should not be set to none.

Token Security

The JWT RFC 7519 allows for the creation of tokens without signatures and without secured / hashed signatures. The ReallySimpleJWT library however imposes security by default as there is no logical reason not to. All created tokens must have a signature and a strong secret, but the library will parse and validate tokens without a secret or a strong secret. The library will not validate tokens without a signature.

By default The ReallySimpleJWT library makes available two encoding implementations, ReallySimpleJWT\Encoders\EncodeHS256 and ReallySimpleJWT\Encoders\EncodeHS256Strong. The latter enforces strict secret security and is used by default to create tokens via the Token and Tokens classes. The EncodeHS256 does not impose strict secret security and can be used with the Build class to create tokens when required. In addition, it is possible to create a custom encode class by implementing the ReallySimpleJWT\Interfaces\Encode interface. See the section Custom Encoding.

Secret Strength

This JWT library imposes strict secret security via the EncodeHS256Strong class. The secret provided must be at least 12 characters in length; contain numbers; upper and lowercase letters; and one of the following special characters *&!@%^#$.

// Bad Secret
secret123

// Good Secret
sec!ReT423*&

The reason for this is that there are lots of JWT Crackers available meaning weak secrets are easy to crack thus rendering the signature security JWT offers useless.

Framework Integration With PSR-JWT Middleware

You can easily integrate ReallySimpleJWT with PSR-7 / PSR-15 compliant frameworks such as Slim PHP and Laminas by using the PSR-JWT library.

For example integration with Slim PHP only requires a few lines of code:

// Can be added to any routes file in Slim, often index.php.
require '../../vendor/autoload.php';

$app->get('/jwt', function (Request $request, Response $response) {
    $response->getBody()->write("JSON Web Token is Valid!");

    return $response;
})->add(\PsrJwt\Factory\JwtAuth::middleware('Secret123!456$', 'jwt', 'Authentication Failed'));

Please read the PSR-JWT documentation to learn more about integration options for ReallySimpleJWT.

Browser Integration With RS-JWT

When you create JSON Web Tokens you may wish to read some of the information contained in the header and payload claims in the browser.

If you do, we have an NPM packages for that called RS-JWT.

Install:

npm install --save rs-jwt

Usage:

import { parseJwt } from 'rs-jwt'

const result = parseJwt('json.web.token')

// Return the header claims as an object.
const header = result.getHeader()

// Access the type claim.
console.log(header.typ)

// Return the payload claims as an object.
const payload = result.getPayload()

// Access the expiry claim.
console.log(payload.exp)

For more information see the project README or visit the NPM Page.

License

MIT

Author

Rob Waller

Twitter: @RobDWaller

reallysimplejwt's People

Contributors

b3none avatar joelcuevas avatar pixeline avatar robdwaller avatar szepeviktor 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

reallysimplejwt's Issues

Validate->notBefore should allow same sec timestamp

notBefore fails if the request is checked in the same timestamp it was generated: timestamp is 1000ms vs a HTTP request of few 10 to 100ms.
replace
$notBefore < time()
by
$notBefore <= time()
in
Validate.php
this also does not allow for any clock drift between systems

It Doesn't work

Nothing to explain I SPENT ONE SUNDAY IN THIS LIBRARY
ReallyDoesn'tWorkJWT

When/how to refresh the token

Hi Rob,

We are currently implementing ReallySimpleJWT, but we have one question. When/how do we refresh the token? If we set an exp time of 3600 seconds, does the client need to contact the server for a new token, or does the server do this itself and send the new token whenever the client contacts the server?

The situation that made this question occur to me is like this: When the client needs to ask the server a new token every hour, but at the end of the day they shutdown their PC and go home. Do they need to log in that next morning, or will they contact the server with the old token and get an up-to-date one?

I hope I've made my question clear!

Kind regards :)

Improvements

Thanks for this cool project.

Some small possible improvements:

  • You define a DateTime class that provides and interface to the Carbon Date Time library.
    So use it everywhere and do not expose / use Carbon classes elsewhere.

  • You split and decode the same token more than once when you validate it and get it's payload.
    (The first time in Token::validate and a second time in Token::getPayload)
    Validate expiration decode the payload and json_decode it. You do it again in Token::getPayload

Have fun.

"Call to undefined method ReallySimpleJWT\Token::validateExpiration()"

Hello,

While it was working flawlessly before, I suddenly got this error.

2022/01/03 22:28:51 [error] 2739#2739: *1635 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined method ReallySimpleJWT\Token::validateExpiration() in /var/.......php:23

What could be the cause of this error?

Server: Nginx 1.18 PHP-FPM

Why i can't use my own JWT secret?

While using my own secret, i am getting this error

Fatal error: Uncaught ReallySimpleJWT\Exception\ValidateException: Invalid secret. in /Applications/MAMP/htdocs/xxxxxxx/assets/libs/vendor/rbdwllr/reallysimplejwt/src/Build.php:153

What is purpose of validating secret while building jWT?

if (!$this->secretValidator->validate($secret)) {
  throw new ValidateException('Invalid secret.', 9);
}

nesbot/carbon dependency conflicts with illuminate/support package

Hi there!!

I read your blog post and am trying to implement your library in my current project. I'm using the illuminate/database component from Laravel, which installs the illuminate/support package, which requires nesbot/carbon "^1.24.1".

I'm getting the following output when attempting to require your package into my project:

- Conclusion: don't install rbdwllr/reallysimplejwt 1.0.4
- Conclusion: don't install rbdwllr/reallysimplejwt 1.0.3
- Conclusion: don't install rbdwllr/reallysimplejwt 1.0.2
- Conclusion: don't install rbdwllr/reallysimplejwt 1.0.1
- Conclusion: remove nesbot/carbon 1.32.0
- Installation request for rbdwllr/reallysimplejwt ^1.0 -> satisfiable by rbdwllr/reallysimplejwt[1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4].
- Conclusion: don't install nesbot/carbon 1.32.0
- rbdwllr/reallysimplejwt 1.0.0 requires nesbot/carbon 1.22.* -> satisfiable by nesbot/carbon[1.22.0, 1.22.1].
- Can only install one of: nesbot/carbon[1.22.0, 1.32.0].
- Can only install one of: nesbot/carbon[1.22.1, 1.32.0].
- Installation request for nesbot/carbon (locked at 1.32.0) -> satisfiable by nesbot/carbon[1.32.0].

I'm not too familiar with the workings of the carbon library, but was wondering if this could be resolved or not?

Thanks again and awesome package.

Get payload without the token secret like on jwt.io?

Question should say everything.
Why do i have to insert the token secret when i just want for example my uid value from the payload.
I mean when i am posting my token inside https://jwt.io/#debugger-io i can also just access my values.

Edit: Just figured out you can also just pass an empty string into the getPayload function. But please update your code and the documentation to make this argument optional!

Documentation incorrect

Hi Mr Waller,

Firstly, awesome library.

Secondly, I believe the readme needs an update.

validateExpiration is performed in validate, and validateExpiration is no longer part of Token?

Secret validation is too strict - can't generate the token correctly

I'm trying to generate a JWT to use with 3rd party API.

The secret/key I have doesn't contain any symbols (alphanumeric only) so I can't get this library to generate a valid JWT that the 3rd party will accept.

Is there a reason the secret is validated in such a way? Can it be loosened to allow alphanumeric only secrets? Is it part of the JWT 'spec' for it need to contain symbols?

error: Uncaught Error: Class 'ReallySimpleJWT\TokenBuilder' not found

just for test i created an index.php in scr folder
mycode:

<?php
include 'Token.php';
use ReallySimpleJWT\Token;

$token = Token::getToken('userIdentifier', 'secret', 'dateTimeString' | 'dateTimeNumber', 'issuerIdentifier');

full error message:
Fatal error: Uncaught Error: Class 'ReallySimpleJWT\TokenBuilder' not found in C:\wamp64\www\test\src\Token.php:77 Stack trace: #0 C:\wamp64\www\test\src\Token.php(28): ReallySimpleJWT\Token::builder() #1 C:\wamp64\www\test\src\index.php(5): ReallySimpleJWT\Token::getToken('userIdentifier', 'secret', 'dateTime_u\x7Fkow', 'issuerIdentifie...') #2 {main} thrown in C:\wamp64\www\test\src\Token.php on line 77

jsonDecode method can return null

It's seems it is feasible the jsonDecode method in the JsonEncoder helper can return null in some cases, an issue to be looked at.

TypeError: Return value of ReallySimpleJWT\Parse::jsonDecode() must be of the type array, null returned

vendor/rbdwllr/reallysimplejwt/src/Helper/JsonEncoder.php:35
vendor/rbdwllr/reallysimplejwt/src/Parse.php:250
vendor/rbdwllr/reallysimplejwt/src/Parse.php:221
vendor/rbdwllr/reallysimplejwt/src/Parse.php:106

Invalid signature

$this->builder = new \ReallySimpleJWT\TokenBuilder();
$this->builder->addPayload(["key" => "UserID", "value" => $userId]) // $userId = 5
        ->setSecret(JWT::$SECRET_KEY) // = "sec!ReT423*&"
        ->setExpiration(date("Y-m-d H:i:s", strtotime('+1 hours')))
        ->setIssuer("MY-APP")
        ->build();

(Copied from documentation, just changed UserID)

Output:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjUsImlzcyI6Ik1TQ1AiLCJleHAiOjE1MzU0NzY1NzYsInN1YiI6IiIsImF1ZCI6IiJ9.jCuaGJy3H1rkCjFwn4sIe9VetQ5wYgAz5NZD46YiKdgeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjUsImlzcyI6Ik1TQ1AiLCJleHAiOjE1MzU0NzY1NzYsInN1YiI6IiIsImF1ZCI6IiJ9.jCuaGJy3H1rkCjFwn4sIe9VetQ5wYgAz5NZD46YiKdg

This contains 4x ., but it should only contain it 2 times.

https://jwt.io/ also tells "Invalid signature"

Im using PHP Version 7.2.8 with xampp.

greetings from germany
Jonas

PHP Version Required?

I was having trouble with an error that the Token::customPayload function didn't exist, and tracked it down to the fact that composer had installed v1.1 of reallysimplejwt. When I tried forcing it to install version 2.0, I get:

Package rbdwllr/reallysimplejwt at version 2.0 has a PHP requirement incompatible with your PHP version (7.0.33)

So which PHP version is required? Thanks!

Private - Public Key Encryption Support ??

I'm not too familiar with signing of JWT's, but there is a NGINX package here: ngx-http-auth-jwt-module that supports:

"The algorithm to use. One of: HS256, HS384, HS512, RS256, RS384, RS512"

I compiled that module and tried it out. It seems to work quite well. I had been using ReallySimpleJWT a little previously, so it was convenient when testing out that other NGINX package.

Does this package support asymmetric keys ? If not, is that something that could be added to the package ? That NGINX module also requires the 'password' if using HS256 to be in BINHEX format, which is fine, but just worth noting.

Stephen D. Scotti

nbf not set when creating simple but then validates

Not sure whether this is by design but when I created my token and then validated it, the nbf value is validated however that part of the token is not set hence it will always raise the error when validating it's own tokens.

Mistake in ReadMe Documentation

There is a mistake in the ReadMe documentation. It currently reads.

<?php

use ReallySimpleJWT\TokenBuilder;

$builder = new TokenBuilder();

$token = $builder->addPayload('key', 'value')
    ->addPayload(['key' => 'foo', 'value' => 'bar'])
    ->setSecret($secret)
    ->setExpiration($expiration)
    ->setIssuer($issuer)
    ->build();

You should remove the first addPayload method as it is wrong.

500 Internal Server Error

The token generated and validated work perfectly on localhost, but not on the remote server. I get 500 Internal Server Error, without any php error.

PHP Version | 5.4.45-0+deb7u11

Returns a malformed JWT payload

I'm using PHP 7.1, MySQL 5.6 and NGINX on Ubuntu 16.04 server

It would appear the server returns a malformed JWT string without payload.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..cZDpuZIgW0341pb7-4t-rRnhrItIIPfBknARJInVPz4

My PHP code:

$token = $builder->addPayload(["key" => "userId", "value" => $user->getId()])
                     ->addPayload(["key" => "firstName", "value" => $user->getFirstName()])
                     ->addPayload(["key" => "lastName", "value" => $user->getLastName()])
                     ->addPayload(["key" => "email", "value" => $user->getEmail()])
                     ->addPayload(["key" => "role", "value" => $user->getRole()])
                     ->addPayload(["key" => "phone", "value" => $user->getPhone()])
                     ->setSecret("@NFmuyc9k*Ia")
                     ->setExpiration(time() + 18000)
                     ->setIssuer("127.0.0.1")
                     ->build();
    echo json_encode($token);

Only Works With PHP 7.1

I am currently using php 7.0 on my prod server, and composer installs version 1.x which is not found by autoloader.

Locally I got the version 2.x and works great. only 7.0 has a bug in the autoloader.

Audience validation?

Hi! I'm currently using your library in a refactoring of a legacy application around the Container of Laravel, rewriting all to get it into the full framework would be too costly. This library is currently helping me a lot to implement a sane authentication.

I'm just about to get into the authorization and I was thinking about using the audience claim, so I'd like to know if you have any plans or would be accepting PR to implement this as part of the library itself. Or don't and it should be something I could implement in a separate package.

Thanks for contributing this to the community and I look forward to a contribution if you are interested.

Fix syntax errors in README

Rob, there are a number of PHP syntax errors in the README doc examples. Fix these.

See this pull request as an example: #39

exp time in generated token should be an epoch number

Hi,

I was trying to use this library to generate JWT tokens that could then be used to talk to another server running node (running express-jwt) however my tokens were getting rejected, after some digging I found that this library seemed to be generating the exp times as date strings rather than epoch numbers (even if you pass in an epoch number) I think this is because you are using a DateTime to parse the input and when you are outputting you're not using a formatter e.g. ->format('U')

I was in a bit of a rush so I've used a different library but thought I would flag it up for you. Some relevant links below for anyone looking to make a fix. I haven't checked but I'd guess it's probably the same with any other dates e.g. iss

exp time should be a NumericDate, definition of a NumericDate

Proposal: Add support for KID claim

Relevance

We need to use separate secrets depending on the service/client that requires auth.

This is difficult with the current setup since we need the key to get the header in Token::getHeader()

We, therefore, need to parse and get the kid claim from the header ourselves first - repeating logic and complicating things.

Proposal

Something like:

<?php

declare(strict_types=1);

namespace ReallySimpleJWT;

/**
 * Value object for the generated JSON Web Token, takes the token and
 * the secret.
 *
 * @author Rob Waller <[email protected]>
 */
class Jwt
{
    /**
     * The JSON Web Token string
     *
     * @var string $token
     */
    private $token;

    /**
    * The secret used to create the JWT signature
    *
    * @var string $secret
    */
    private $secret;

    /**
     * JWT Constructor
     *
     * @param string $token
     * @param string|array $secret Array to auto-determine secret from kid=>secret mapping
     */
    public function __construct(string $token, $secret)
    {
        $this->token = $token;

        if (is_string($secret)) {
            $this->secret = $secret;

            return;
        }

        $this->secret = $secret[$this->getKid()];
    }

    /**
     * Return the JSON Web Token String
     *
     * @return string
     */
    public function getToken(): string
    {
        return $this->token;
    }

    /**
     * Return the secret used to encode the JWT signature
     *
     * @return string
     */
    public function getSecret(): string
    {
        return $this->secret;
    }

    /**
     * @return string
     */
    private function getKid(): string
    {
        $header = substr(
            $this->token,
            0,
            strpos($this->token, '.')
        );

        $header = json_decode(base64_decode($header), true);

        return $header['kid'];
    }
}

Installation

Would be useful to have instructions on how to install / incorporate into PHP web page. I am an experienced programmer, but am admittedly new to PHP. The documentation is skant on how to get it going. A few sentences would go a long way to making what looks to be a great project - even better. Any help on how to get it going on my PHP site? What files are needed on the server? How to incorporate into an existing PHP website? Thank you in advance for the help.

Suggestion: rename var $hash within TokenAbstract

Hi,

first thanks for this great piece of work. I am looking for a jwt php library, as I am not really experienced with php. But as this is a very critical part I tried to understand the implementation.

I had a hard time to understand why a hash is fed to the signature and there used as algorithm - until I figured out it was just the name of the variable that kept me away from understanding the code. Perhaps it would make complex things easier to understand if a algorithm is named as such...

Merry Christmas,
Dietmar

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.