我试图在令牌过期后刷新,但我真的丢失了。有人能给我举个例子吗?在我使用委托过滤器根据用户角色限制我的路由后,我得到不同的错误消息,以前是{"error":"token_expired"}
,现在是(TokenExpiredException in PayloadValidator.php line 74:Token has expired)
。
我使用JWT文档的典型身份验证:
public function getAuthenticatedUser()
{
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon'JWTAuth'Exceptions'TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon'JWTAuth'Exceptions'TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon'JWTAuth'Exceptions'JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return response()->json(compact('user'));
}
我刚刚设法解决了这个问题。方法如下:
在getAuthenticatedUser()
和authenticate()
方法所在的同一个控制器中,我放置了一个令牌刷新方法:
public function refresh(Request $request)
{
try {
$current_token = $request->get('token');
//$current_token = JWTAuth::getToken();
if(!$current_token) return response()->json(null);
$token = JWTAuth::refresh($current_token);
return response()->json(compact('token'));
} catch (JWTException $e) {
if ($e instanceof TokenExpiredException) {
return response()->json(['token_expired'], $e->getStatusCode());
} else if ($e instanceof TokenBlacklistedException) {
return response()->json(['token_blacklisted'], $e->getStatusCode());
} else if ($e instanceof TokenInvalidException) {
return response()->json(['token_invalid'], $e->getStatusCode());
} else if ($e instanceof PayloadException) {
return response()->json(['token_expired'], $e->getStatusCode());
} else if ($e instanceof JWTException) {
return response()->json(['token_invalid'], $e->getStatusCode());
}
}
}
和相应的路由:
Route::post('authenticate', 'AuthenticateController@authenticate');
Route::post('refresh', 'AuthenticateController@refresh'); // The new route.
现在,因为我们使用AngularJS作为我们的前端和所有的HTTP请求,我们决定令牌是否已经过期。不确定这是否适用于您的项目,但也许您可以使用逻辑原则。
如果你不使用AngularJS作为你的前端,并且对我们的前端逻辑不感兴趣,它是在AngularJS中构建的,你可以现在停止阅读
在我们的AngularJS主文件app.js
中,我们使用UI-Router
进行基于状态的路由(以及jwtHelper-library
):
app.run(function($rootScope, $state jwtHelper, AuthFactory) {
// Checks if the token has expired on every view change.
$rootScope.$on('$stateChangeStart', function(e, to) {
if (to.data.requiresLogin && jwtHelper.isTokenExpired(store.get('token')) {
AuthFactory.attemptRefreshToken();
}
});
});
// We use a http interceptor to listen for the Token Expired-exception
// coming from the backend (Laravel 5.1 and JWTAuth) on any http calls performed.
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
});
// The actual interceptor.
app.factory('httpInterceptor', function ($q, store, $injector) {
return {
// On every request that returns an error, check if the status code is
// 401 ('unauthorized'), which means the token has expired.
responseError: function(response) {
if (response.status == 401){
var AuthFactory = $injector.get('AuthFactory');
// Pass the attempted response config in order to retry the request after the refresh.
return AuthFactory.attemptRefreshToken(response.config);
}
}
};
});
最后但并非最不重要的是,我们实际的刷新调用它存储在AuthFactory文件中:
attemptRefreshToken: function(requestTodoWhenDone){
var token = store.get('token');
return $http({
method: 'POST',
skipAuthorization: true,
url: ApiEndpoint.url + 'refresh',
data: {token: token}
})
.success(function(response)
{
// Set the refreshed token.
store.set('token', response.token);
})
.then(function(){
// Attempt to retry the request if request config is passed.
if(!angular.isUndefined(requestTodoWhenDone) && requestTodoWhenDone.length > 0)
{
// Set the new token for the authorization header.
requestTodoWhenDone.headers = {
'Authorization': 'Bearer ' + store.get('token')
};
// Run the request again.
return $http(requestTodoWhenDone);
}
});
});