我不明白 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
I don't understand JWT refresh token's behaviour (LARAVEL)
提问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.
好的,我终于有一些有用的东西了。
Remove "jwt.refresh" from your middleware. This is for one-pass-tokens as I′ve commented above.
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
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.
从中间件中删除“jwt.refresh”。正如我在上面评论的那样,这是针对一次性令牌的。
我无法让 JWTAuth::refresh() 在启用黑名单的情况下工作。当我调用 JWTAuth::refresh() 时会抛出“TokenBlacklistedException”,即使我知道它只是因为我在“TokenExpiredException”的 catch 块中执行此操作而过期。漏洞?解决方法:
JWT_BLACKLIST_ENABLED=false
如果 /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,我的令牌现在可以使用一天。