tymondesigns / jwt-auth

🔐 JSON Web Token Authentication for Laravel & Lumen
https://jwt-auth.com
MIT License
11.27k stars 1.55k forks source link

The `refresh` function returning the same token and it's expired! #1000

Open Mahmoudz opened 7 years ago

Mahmoudz commented 7 years ago

I'm using the Dingo API package with this JWT package.

Here's my straight forward code from the controller:

// getting the current token
$oldToken = $request->bearerToken();

        // > just for debugging:
        // decoding the old token to check the expiry date
        $payload = JWTAuth::decode(new Token($oldToken));
        $new_expires_at = date('d M Y h:i', $payload->get('exp'));
        dump($new_expires_at);

// refreshing the old token and getting a new one
$newToken = JWTAuth::refresh($oldToken);

        // > just for debugging:
        // decoding the new token to check the expiry date
        $payload = JWTAuth::decode(new Token($newToken)); // <<<<<<<<<< causes the error 
        $new_expires_at = date('d M Y h:i', $payload->get('exp'));
        dump($new_expires_at);

Here's the result of that code:

{"message":"The token has been blacklisted","status_code":500}

When disabling the blacklisting feature 'blacklist_enabled' => false

The new Token returned is the exact old Token with the same expiry date!!

WHY!

Mando-Chris commented 7 years ago

Hi @Mahmoudz

The version of the api I am using doesn't have JWTAuth::decode in it, so my information may not apply. What version are you using?

Not sure if this helps, but

  1. JWTAuth::refresh doesn't take an old token, it gets and uses the token from the request itself I believe. It takes optional bool params (see JWT->refresh I believe).
  2. It builds the token from the "claims" payload. Since the token is an encryption of the payload, if the payload doesn't change in anyway, you would get the same token?

good luck

Mahmoudz commented 7 years ago

@Mando-Chris I'm using version 0.5.10.

JWTAuth::refresh does take token as input and it's optional.

    public function refresh($token = false)
    {
        $this->requireToken($token);

        return $this->manager->refresh($this->token)->get();
    }

All it's doing after getting the token is this:

    public function refresh(Token $token)
    {
        $payload = $this->setRefreshFlow()->decode($token);

        if ($this->blacklistEnabled) {
            // invalidate old token
            $this->blacklist->add($payload);
        }

        // return the new token
        return $this->encode(
            $this->payloadFactory->make([
                'sub' => $payload['sub'],
                'iat' => $payload['iat'],
            ])
        );
    }
Mando-Chris commented 7 years ago

@Mahmoudz Just realized we are using the develop branch.

So my points are not relevant to you, sorry about that.

Mahmoudz commented 7 years ago

@Mando-Chris thanks anyway man :)

willgopublic commented 7 years ago

Do you try to refresh after the TTL, i.e. before exp is in the past?

Walk-Code commented 7 years ago

@Mahmoudz I have the same problem, may I ask you?

boukeversteegh commented 6 years ago

In case this problem occurs within unit tests, when performing two requests in the same test:

try to run $this->refreshApplication(), to clear the Request object that was stored by JWT from the first request