我不明白 JWT 刷新令牌的行为 (LARAVEL)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41325250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:00:11  来源:igfitidea点击:

I don't understand JWT refresh token's behaviour (LARAVEL)

phplaraveljwt

提问by darkylmnx

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

我刚刚用 LARAVEL 和这个https://github.com/tymondesigns/jwt-auth尝试过 JWT 身份验证

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

我所理解的是:令牌的有效期为 1 小时,可以在 2 周内刷新

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

但是 3 小时后,如果我尝试查询某些内容,它会显示“令牌已过期”。

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.

这个系统是否意味着,用户必须在每小时内更新/刷新他的令牌,但限制为 2 周?我不明白。

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 ?

用户如何在这种系统上持续登录?在第一个小时之后刷新令牌如何有用,虽然还不到 2 周,但我无法获得新令牌?

thanks

谢谢

UPDATE: CODE

更新:代码

config/jwt.php

配置/jwt.php

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

routes/api.php

路线/api.php

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

Http/Controllers/AuthController

Http/控制器/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 :

这是流程:

requestto /loginwith {username: xxx, password: xxx} responseof /login> {token: xxxxxxx}

请求/登录与{用户名:XXX,密码:XXX} 响应/登录> {令牌:XXXXXXX}

requestto /teststraight after (10 secs) with Bearer xxxxxxresponseof /test> the good json response with NEW TOKEN in HEADER

请求/测试直后(10秒)与承载XXXXXX响应/测试>在HEADER与新令牌良好JSON响应

requestto /testafter 3 minutes (so 3mins 10 secs have past now, less than the 5min of refresh limit) responseof /test> token expired

请求/测试3分钟(这样3mins 10秒有过去现在,小于的刷新限制在5分钟)后 响应/测试>令牌过期

I don't understand.

我不明白。

回答by jps

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".

但是 3 小时后,如果我尝试查询某些内容,它会显示“令牌已过期”。

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.

这个系统是否意味着,用户必须在每小时内更新/刷新他的令牌,但限制为 2 周?我不明白。

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.

是的。您将刷新令牌保留在客户端系统中,并在访问令牌过期时使用它来请求新的访问令牌。

回答by Johan

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.

  1. 从中间件中删除“jwt.refresh”。正如我在上面评论的那样,这是针对一次性令牌的。

  2. 我无法让 JWTAuth::refresh() 在启用黑名单的情况下工作。当我调用 JWTAuth::refresh() 时会抛出“TokenBlacklistedException”,即使我知道它只是因为我在“TokenExpiredException”的 catch 块中执行此操作而过期。漏洞?解决方法:

    JWT_BLACKLIST_ENABLED=false

  3. 如果 /test 返回 401,您需要有一个可以调用的刷新端点。我使用与 login 相同的方法,但在我的情况下它是一种自定义。

...
    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
    } ...

回答by Anana Aristotle

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

这就是我为我做的,我必须通过这样做将令牌时间设置为 24 小时

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

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

我把 60 改为 1440,我的令牌现在可以使用一天。