2015-09-07 76 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