Minimal and flexible package to extend Sanctum to have refresh token as well.
You can install the package via composer:
composer require albetnov/sanctum-refresh
Then you'll need to push and run the migration with:
php artisan vendor:publish --tag="sanctum-refresh-migrations"
php artisan migrate
You can also publish the config file with:
php artisan vendor:publish --tag="sanctum-refresh-config"
This is the contents of the published config file:
return [
/**
* Set the fallback expiration time of both tokens
* Time in minutes.
*/
'expiration' => [
// set the fallback of access token expiration
'access_token' => 2, // 2 minutes,
// set the fallback of refresh token expiration
'refresh_token' => 30, // 30 minutes
],
];
<?php
namespace App\Http\Controllers;
use Albet\SanctumRefresh\Services\TokenIssuer;
class TokenController {
function newToken() {
$token = TokenIssuer::issue($request->user(), guard: 'api');
return response()->json([
'message' => 'Token generated successfully!',
'data' => $token->toArray(),
]);
}
}
Response schema:
{
"message": "Token generated successfully!",
"data": {
"access_token": "[string]",
"access_token_expires_at": "[Y-m-d H:i:s]",
"refresh_token": "[string]",
"refresh_token_expires_at": "[Y-m-d H:i:s]"
}
}
Refresh Token Middleware (optional, if you want to customize error based on expired, invalid format, etc)
<?php
// (...)
use Albet\SanctumRefresh\Helpers;
use Albet\SanctumRefresh\Exceptions\SanctumRefreshException;
class TokenMiddleware {
public function handle(Request $request, \Closure $next): Response {
try {
Helpers::getRefreshToken(
$request->get('refresh_token', '') // adjust to your liking, either from Query Parameter, Body, or Header.
);
return $next($request);
} catch (SanctumRefreshException $e) {
// handle tags of SanctumRefreshException
return response()->json([
'error' => 'Refresh token invalid'
], 400);
}
}
}
<?php
// imports...
Route::post('refresh-token', [TokenController::class, 'refreshToken'])->middleware(TokenMiddleware::class);
<?php
use Albet\SanctumRefresh\Services\TokenIssuer;
class TokenController {
public function refreshToken(Request $request) {
$newToken = TokenIssuer::refreshToken($request->get('refresh-token', ''));
if(!$newToken) {
return response()->json([
'error' => 'Refresh token not valid',
], 400);
}
return response()->json([
'message' => 'New token created',
'data' => $newToken->toArray(),
]);
}
}
Register prune:token
on your commands Kernel.php
, you can run it as cron job:
Schedule::command('prune:token')->daily();
Run the tests:
composer test
Figure out the code coverage:
composer test-coverage
Please see Changelog for more information.
You are free to contribute to this project.
The MIT License (MIT). Please see License File for more information.