Slim 4 - JWT (Tuupola) - Signature verification failed

Hi everyone,

I am generating a JWT token which is sent in the Authorization header.

Before digging into the code I’d like to note that I did verify the token found in the logs on and I have also verified the timestamps sent in the payload on this website. Everything looks good so far. The token received seems to be correct (key verified and no error in the timestamps). I am on a development machine running PHP 7.4 and everything is done locally (no possible timezone error) and, just to make absolutely sure there is nothing wrong with the timing, the “iat” is generated with a timestamp 2 days ago and the “exp” is two days in the future.

I am not using Apache in development but PHP’s webserver started with the following command:

php -S localhost:8000 -t public

Here is an abstract of my composer.json

"require": {
        "firebase/php-jwt": "^5.0",
        "monolog/monolog": "^2.0",
        "nyholm/psr7": "^1.2",
        "nyholm/psr7-server": "^0.4.1",
        "php-di/php-di": "^6.0",
        "selective/config": "^0.1.1",
        "slim/http": "^0.8.0",
        "slim/slim": "^4.0",
        "tuupola/base62": "^2.0",
        "tuupola/cors-middleware": "^1.1",
        "tuupola/slim-basic-auth": "^3.2",
        "tuupola/slim-jwt-auth": "^3.4"

Here is my jwt middleware

use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;

use Slim\App;

return function (App $app) {

$logger = new Logger("slim");
$rotating = new RotatingFileHandler(__DIR__ . "/../logs/slim.log", 0, Logger::DEBUG);

$app->add(new \Tuupola\Middleware\JwtAuthentication([
    "path" => "/api",
    "ignore" => ["/api/user/register","/api/auth"],
    "algorithm" => ["HS256","HS512"],
    "logger" => $logger,
    "secret" => "thisisnotmyrealsecret"


How the JWT token is generated:

$now = new DateTime("now -2 days");
$future = new DateTime("now +2 days");
$jti = (new Base62)->encode(random_bytes(32));

$payload = [
      "jti" => $jti,
      "iat" => $now->getTimeStamp(),
      "exp" => $future->getTimeStamp()
$token = JWT::encode($payload, $this->jwt->secret, "HS512");
return $response->withJson($result)->withStatus(201);

The token is well received and identified in Postman and successfully sent back as the “Authorization” header to the PHP server but is not decoded correctly (apparently).

In the logs I find:

[2019-12-23T05:17:44.077009+00:00] slim.DEBUG: Using token from request header [] []
[2019-12-23T05:17:44.078120+00:00] slim.WARNING: Signature verification failed ["eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJqdGkiOiJ0UmRqZXp2MmlXSGJ4UEo2RVBxWnRpYXNZVWlSQTloM2Q0bDU3RDU2WHc4IiwiaWF0IjoxNTc2OTA1NDYwLCJleHAiOjE1NzcyNTEwNjB9.Jvn_h5hYGchDAHq3mszLTeGXkJzXJIlxha1bPv8b8XzIyxj_efGFK9yWBdqsNNFNsiVTfqGOWy0xHDfh89vE9Q"] []

What really kills me is that if I copy and paste the token found in the logs and check it again to debug it, it is perfectly correct and valid… Including the timestamps and key verification.

I must be doing something wrong somewhere.

Could you help me?

Alright! The issue was between the chair and the screen :smiley:

Actually the value of the “secret” was set to “null” I had to adapt my code to get the value from an environment variable.

Problem solved!

1 Like