我只是設法解決這個問題。具體方法如下:
在同一控制器作爲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', '[email protected]');
Route::post('refresh', '[email protected]'); // 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);
}
});
});
它的實際工作,但我在我的新令牌被列入黑名單的問題,我有幾乎相同的設置,你有我只是用satellizer來發送令牌,我把它們存儲在localStorage的。 –
對,我們很快就注意到了這一點。我在回答後做了以下事情: - 爲了讓Angular能夠檢測到令牌是否列入黑名單,我們不得不將黑名單標記作爲後端的例外。 - 由於我不熟悉的一些錯誤,我們也將HTTP請求從工廠移到了主app.js。 - 我們發送令牌作爲請求參數,而不是使用JWT的內置身份驗證。 查看我的更新回答。 – Mattias