我在laravel中使用tymon jwt auth package进行令牌身份验证,我试图刷新JWT
令牌,如果它已过期,我已经设置了一个中间件AuthenticateToken
,看起来像这样:
class AuthenticateToken
{
public function handle($request, Closure $next)
{
try
{
if (! $user = JWTAuth::parseToken()->authenticate() )
{
return response()->json([
'code' => 401,
'response' => null
]);
}
}
catch (TokenExpiredException $e)
{
// If the token is expired, then it will be refreshed and added to the headers
try
{
$refreshed = JWTAuth::refresh(JWTAuth::getToken());
$user = JWTAuth::setToken($refreshed)->toUser();
header('Authorization: Bearer ' . $refreshed);
}
catch (JWTException $e)
{
return response()->json([
'code' => 403,
'response' => null
]);
}
}
catch (JWTException $e)
{
return response()->json([
'code' => 401,
'response' => null
]);
}
// Login the user instance for global usage
Auth::login($user, false);
return $next($request);
}
}
我在我的路线上使用那个中间件:
Route::group(['prefix' => 'intranet', 'middleware' => ['token']], function () {
Route::get('intranet-post', 'Api\IntranetController@index');
});
在Vue中,我设置了axios并刷新令牌,如下所示:
// Apply refresh(ing) token
BACKEND.defaults.transformResponse.push((data, headers) => {
if (headers.authorization && store('token', headers.authorization)) {
BACKEND.defaults.headers.common.authorization = headers.authorization;
}
return data;
});
BACKEND.defaults.transformRequest.push((data, headers) => {
headers.authorization = `Bearer ${load('token')}`;
});
Vue.prototype.$http = axios;
Vue.prototype.$backend = BACKEND;
function store(key, value) {
try {
let oldLength = localStorage.length;
localStorage.setItem(key, value);
return !(localStorage.length > oldLength); // Returns true on write error
}
catch (err) {
return true;
}
}
function load(key) {
try {
return localStorage.getItem(key);
}
catch (err) {
return null;
}
}
但是,在令牌到期时,我仍然会得到403
响应。如果我在这里使用中间件dd($e)
:
catch (TokenExpiredException $e)
{
// If the token is expired, then it will be refreshed and added to the headers
try
{
$refreshed = JWTAuth::refresh(JWTAuth::getToken());
$user = JWTAuth::setToken($refreshed)->toUser();
header('Authorization: Bearer ' . $refreshed);
}
catch (JWTException $e)
{
dd($e);
return response()->json([
'code' => 103,
'response' => null
]);
}
}
我明白了:
令牌已被列入黑名单
我该如何解决这个问题?
答案 0 :(得分:0)
试试我的中间件:
<?php
namespace App\Http\Middleware;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Tymon\JWTAuth\Exceptions\JWTException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
class RefreshToken extends BaseMiddleware {
public function handle($request, \Closure $next) {
$this->checkForToken($request); // Check presence of a token.
try {
if (!$this->auth->parseToken()->authenticate()) { // Check user not found. Check token has expired.
throw new UnauthorizedHttpException('jwt-auth', 'User not found');
}
$payload = $this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray();
return $next($request); // Token is valid. User logged. Response without any token.
} catch (TokenExpiredException $t) { // Token expired. User not logged.
$payload = $this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray();
$key = 'block_refresh_token_for_user_' . $payload['sub'];
$cachedBefore = (int) Cache::has($key);
if ($cachedBefore) { // If a token alredy was refreshed and sent to the client in the last JWT_BLACKLIST_GRACE_PERIOD seconds.
\Auth::onceUsingId($payload['sub']); // Log the user using id.
return $next($request); // Token expired. Response without any token because in grace period.
}
try {
$newtoken = $this->auth->refresh(); // Get new token.
$gracePeriod = $this->auth->manager()->getBlacklist()->getGracePeriod();
$expiresAt = Carbon::now()->addSeconds($gracePeriod);
Cache::put($key, $newtoken, $expiresAt);
} catch (JWTException $e) {
throw new UnauthorizedHttpException('jwt-auth', $e->getMessage(), $e, $e->getCode());
}
}
$response = $next($request); // Token refreshed and continue.
return $this->setAuthenticationHeader($response, $newtoken); // Response with new token on header Authorization.
}
}
有关详细信息,请参阅this post。
答案 1 :(得分:0)
你可以编辑你的 config/jwt.php 关于第 224 行。
<?php
.......
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', false),