I hadn't been able to do much development for a while because I was working on Docker... (Still, I understand a lot more about Docker now... enough to use it in
GGAMI·
I hadn't been able to do much development for a while because I was working on Docker... (Still, I understand a lot more about Docker now... enough to use it in general...)
So, the work I'm continuing with is Laravel JWT Refresh Token...
I'm still a bit unclear on the concept of JWT, and I wonder how it's different from sessions (cookies)... There are so many confusing and difficult issues... (Maybe it's just me...)
Anyway, what I have in mind is that a token validity period and a refresh period are specified. (tymon/jwt)
After the validity period expires, if a request is made using the expired token, Laravel middleware issues a new token if the token is still within its refresh period, and responds with the new token value included in the header. (At this point, of course, it also outputs the result)
Then, if the response header received by Nuxt.js (client) contains a token, it determines that a new token has been issued, replaces the old token with the new one, calls user again through the Nuxt.js Auth Module, retrieves the updated payload, and saves it to local storage.
So, that's what I had in mind...
With tymon, once the refresh period has passed, the token is unconditionally rendered unusable.
That's all good... But... I'm currently facing two problems.
Once the token expires, if a request is made within the refresh period and a new token is issued, then after that new token expires, it can no longer be refreshed. (You should be able to keep reissuing tokens as long as you're within the refresh period, but that doesn't work!! It only works once... Why? 😢)
JWT_TTL=1
JWT_REFRESH_TTL=2
I had set the values like this... But it turns out that REFRESH_TTL doesn't keep increasing; it's the final limit. Once the TTL period based on iat has elapsed, the token can no longer be used for anything. (Its final lifetime)
In other words, the correct information is that you can refresh indefinitely until the refresh token period has elapsed.
When you refresh, exp (expiration time) and nbf (activation time) change... (which is to be expected) But the Claims returned by getJWTCustomClaims() are not updated with new data... (What I want is for the token's Claims to be refreshed at the same time as the token itself!! Otherwise, if a nickname changes, or a user's status is set to banned in the meantime, and so on, wouldn't those changes fail to be reflected...? At the very least, I want the Claims values to be refreshed whenever a token is reissued... Otherwise, the token will have to contain only things that rarely change...)
That's about it... I think I should solve problem 1 first, and then tackle problem 2...
If I can't find another way to handle problem 2, the only option is to store just the user value in the token, then return the user's information when fetching the User in Nuxt.js Auth and save that information to local storage...
(In other words, this means that the token Payload can't include the user's email, email verification status, status values, role, and so on....)
I'll get to work on these one by one as soon as I can...
There is so little information about tymon/jwt... It seems I have no choice but to look through the relevant GitHub issues, which is really inconvenient....
There were these two methods.
One method is to refresh the JWT by including the user data...
This method involves modifying the JWT.php source itself... I didn't really want to do that, since it would be a hassle to make the changes every time I upgraded the version or installed the package again, and so on..
Even so, I didn't really want to remove Claims from getJWTCustomClaims(), put only the user value in the token, and retrieve it from where the User data is fetched...
(I don't know why; actually, I think this might have been the easiest way...)
So, the solution I came up with was..
If the token has expired, refresh it, set the refreshed token in Auth, fetch the data through the Payload, and then create a new token. At this point, use the value from the payload for iat, and set sub using tokenById so that the user ID remains the same when creating the new token.
$this->checkForToken($request);
$token = $this->auth->parseToken()->refresh();
// 토큰 새로고침할때, payload 정보도 새로 고쳐야 한다 !!
auth()->setToken($token);
// 새로운 토큰 재 발행 (기존 EXP 유지한 채로)
$payload = auth()->payload();
auth()->invalidate();
$token = auth()->claims(['iat' => $payload['iat']])->tokenById($payload['sub']);
auth()->setToken($token);
Written this way, a new token is created using only the iat and sub of the original token, taken from the payload of the refreshed token.
Then the refreshed token is immediately invalidated and removed.
By setting the new token, with its iat value fixed, in Auth, it can be used as a normal JWT token.
Although this means that issuing a Refresh Token and then removing the token again results in the same work being done twice each time it is refreshed... I thought handling it this way would be better than modifying JWT.php, so I did it this way.. (I suppose it might be possible to get the payload directly without registering the refreshed token in Auth... but doing it in more detail would take more time, so I'll work on it later if it becomes a problem... JWT is difficult..)