access & refresh tokens required for login route but invalidates access?
Subject of the issue
My front-end requires an access_token and refresh_token to be generated together in order to log a user in, and then refresh as intended after the access token expires.
Your environment
| Q | A |
|---|---|
| Bug? | yes |
| New Feature? | no |
| Framework | Laravel |
| Framework version | 8.x |
| Package version | ^1.0 |
| PHP version | 7.x |
Expected behaviour
When I call auth()->refresh() as part of the initial log in route to generate a token, I don't want to invalidate the initial access_token since the user is then unable to log in at all. My front-end requires both the access and refresh as part of the log in route.
Actual behaviour
When I log in, I send a POST request to my login endpoint which returns the token from Auth::attempt() in my $token variable, this is then set as access_token so that my front-end can read it.
My front-end also requires a refresh_token, but this needs to be present at the time of log in to store both, but calling auth()->refresh() invalidates the access_token which is used for my requests, how can I workaround this and prevent this behaviour and effectively generate both my access and refresh tokens:
/**
* Get the token array structure.
*
* @param string $token
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token, )
{
return response()->json([
'access_token' => $token,
'refresh_token' => auth()->refresh(),
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
What I do is auth the user 2 times to have an auth token and refresh token and in the next request get the user and log in again. The default behavior of refresh is to invalidate the old one, but, could be possible to add a parameter to the refresh function to avoid the invalidation of the auth toke.
Sadly, this library does not provide proper solution for refresh tokens, it uses the same token for both access_token and refresh_token.
So what I would do, if refresh_token property is essential for your setup, is change 'refresh_token' => auth()->refresh() to 'refresh_token' => $token
And for refreshing token I usually do this:
Adding this to my routes:
Route::middleware('jwt.check') ->post('refresh', [AuthController::class, 'refresh'])->name('token.refresh');
And to controller:
public function refresh(): Response
{
return $this->respondWithToken($this->guard->refresh());
}