2015-09-07 74 views
1

我試圖刷新令牌後,它已過期,但我真的lost.Could有人爲我提供了一個例子嗎?同樣,我用entrust過濾器來限制我的路線基於用戶角色即時獲取不同的錯誤消息,之前{"error":"token_expired"},現在(TokenExpiredException in PayloadValidator.php line 74:Token has expired)刷新jwt令牌laravel和angularJs

我用一個典型的驗證由智威湯遜文檔:

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')); 


} 

回答

0

我只是設法解決這個問題。具體方法如下:

在同一控制器作爲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); 
      } 
     }); 
}); 
+0

它的實際工作,但我在我的新令牌被列入黑名單的問題,我有幾乎相同的設置,你有我只是用satellizer來發送令牌,我把它們存儲在localStorage的。 –

+0

對,我們很快就注意到了這一點。我在回答後做了以下事情: - 爲了讓Angular能夠檢測到令牌是否列入黑名單,我們不得不將黑名單標記作爲後端的例外。 - 由於我不熟悉的一些錯誤,我們也將HTTP請求從工廠移到了主app.js。 - 我們發送令牌作爲請求參數,而不是使用JWT的內置身份驗證。 查看我的更新回答。 – Mattias