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

Posted

技术标签:

【中文标题】我不明白 JWT 刷新令牌的行为 (LARAVEL)【英文标题】:I don't understand JWT refresh token's behaviour (LARAVEL) 【发布时间】:2017-05-10 13:33:03 【问题描述】:

我刚刚尝试使用 LARAVEL 和 https://github.com/tymondesigns/jwt-auth 进行 JWT 身份验证

但有些东西我无法理解。他们在他们的配置中放置了:

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

据我了解:token 的有效期为 1 小时,可在 2 周内刷新

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

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

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

谢谢

更新:代码

配置/jwt.php

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

路由/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'));
    

这就是流程:

使用用户名:xxx,密码:xxx

请求/login /login响应 > token: xxxxxxx

Bearer xxxxxx 之后(10 秒)

请求 /test /testresponse > HEADER中带有NEW TOKEN的良好json响应

3 分钟后

请求/test(所以现在已经过去了 3 分钟 10 秒,小于 5 分钟的刷新限制) /test响应 >令牌过期

我不明白。

【问题讨论】:

【参考方案1】:

访问令牌过期后,您可以使用刷新令牌获取新的访问令牌,而无需再次要求用户输入其用户名和密码。 只有刷新令牌过期后,用户才需要重新登录。

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

那是因为访问令牌已过期。

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

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

【讨论】:

好吧,即使使用刷新令牌,它也不起作用,使用它说:令牌在一小时后过期 也许我做错了,我怎么能做到这一点:“您可以使用刷新令牌获取新的访问令牌而不要求用户输入”? 您必须将刷新令牌发送到您之前获得访问令牌的同一端点。然后,请求标头应包含 您必须将刷新令牌发送到您之前获得访问令牌的同一端点。然后,请求标头应包含 grant_type=refresh_token refresh_token= 回复将是一个新的访问令牌,只有使用新的访问令牌,您才能再次访问数据。 你能给我看一个简单的sn-p吗,因为我做不到。问题是,如果我尝试获取一个端点并且它失败了,那么我必须在重新尝试我的端点之前尝试刷新令牌,在我看来它给出了一个非常奇怪的流程。 Si 我的 UPDATED POST 知道我有什么【参考方案2】:

好的,我终于找到了可行的方法。

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

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

    JWT_BLACKLIST_ENABLED=false

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

... 尝试 if($token = JWTAuth::getToken()) JWTAuth::checkOrFail(); $user = JWTAuth::authenticate(); 捕获(TokenExpiredException $e) JWTAuth::setToken(JWTAuth::refresh()); $user = JWTAuth::authenticate(); if($user /*&& 检查 $user 参数是否*/) 返回响应()->json([ '用户' => $user->profile(), 'accessToken'=> JWTAuth::getToken()->get(), ], 200); 别的 返回响应()->json(假,401); //显示登录表单 ...

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

您可以从路由中删除 jwt.refresh 中间件。

以上是关于我不明白 JWT 刷新令牌的行为 (LARAVEL)的主要内容,如果未能解决你的问题,请参考以下文章

laravel / angularjs JWT 令牌刷新

如何在 Laravel 5.7 中生成 JWT 刷新令牌

Laravel JWT 刷新令牌中间件和并发请求

过期后如何刷新 JWT 令牌(Angular 1.5 + Laravel 5.2)

Laravel JWT 令牌在身份验证 JWT 方法中刷新后无效

Laravel JWT 身份验证