4
votes

I have just tried JWT auth with LARAVEL and this https://github.com/tymondesigns/jwt-auth

But there's something i can't understand. In their config they put :

'ttl' => env('JWT_TTL', 60), // in munutes
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160), // in minutes

What i understant : the token's live is 1hour and can be refreshed within 2 weeks

But after 3hours, if i try to query something, it says "token expired".

Does this system mean, a user must get his token updated / refreshed within every hour but with a limit of 2 weeks ? I don't get it.

How can a user persist login with this kind of system ? How is the refresh Token useful when after the first hour, though it hasn't been 2 weeks yet, i can't get a fresh token ?

thanks

UPDATE: CODE

config/jwt.php

'ttl' => 2, // 2 minutes
'refresh_ttl' => 5, // 5 minutes

routes/api.php

Route::post('/login', 'AuthController@login');
Route::get('/test', 'AuthController@test')->middleware('jwt.auth', 'jwt.refresh');

Http/Controllers/AuthController

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

class AuthController extends Controller
{
    public function test()
    {
        return response()->json(['coucou' => 1]);
    }

    public function login(Request $request)
    {
        // grab credentials from the request
        $credentials = $request->only('email', 'password');

        try {
            // attempt to verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            // something went wrong whilst attempting to encode the token
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        // all good so return the token
        return response()->json(compact('token'));
    }
}

AND THIS IS THE FLOW :

request to /login with {username: xxx, password: xxx} response of /login > {token: xxxxxxx}

request to /test straight after (10 secs) with Bearer xxxxxx response of /test > the good json response with NEW TOKEN in HEADER

request to /test after 3 minutes (so 3mins 10 secs have past now, less than the 5min of refresh limit) response of /test > token expired

I don't understand.

3

3 Answers

4
votes

After the access token is expired you can use the refresh token to get a new access token without asking the user to input his username and password again. Only after the refresh token is expired, the user needs to login again.

But after 3hours, if i try to query something, it says "token expired".

that's because the access token is expired.

Does this system mean, a user must get his token updated / refreshed within every hour but with a limit of 2 weeks ? I don't get it.

yes. You keep the refresh token in your client system and use it to request a new access token when the access token is expired.

2
votes

Ok, finally I have something that works.

  1. Remove "jwt.refresh" from your middleware. This is for one-pass-tokens as I´ve commented above.

  2. I couldn´t get JWTAuth::refresh() to work with blacklists enabled. A "TokenBlacklistedException" is thrown when I call JWTAuth::refresh() even though I know its only expired since I do this in the catch block for "TokenExpiredException". Bug? Workaround:

    JWT_BLACKLIST_ENABLED=false

  3. You need to have a refresh endpoint you can call if /test returns 401. I use same as login, but it´s kind of custom in my case.

...
    try
    {
      if($token = JWTAuth::getToken())
      {
        JWTAuth::checkOrFail();
      }
      $user = JWTAuth::authenticate();
    }
    catch(TokenExpiredException $e)
    {
      JWTAuth::setToken(JWTAuth::refresh());
      $user = JWTAuth::authenticate();
    }
    if($user /*&& check $user against parameter or not*/) 
    {
       return response()->json([
          'user' => $user->profile(),
          'accessToken'=> JWTAuth::getToken()->get(),
       ], 200);
    }
    else 
    {
        return response()->json(false, 401); //show login form
    } ...
1
votes

This is what I did for mine, I have to set the token time to be valid to 24 hours by doing this

'ttl' => env('JWT_TTL', 1400)

I changed the 60 to 1440, and my token now last for a day.