【问题标题】:How to refresh data after refresh token refreshes jwt刷新令牌刷新jwt后如何刷新数据
【发布时间】:2017-10-12 07:11:58
【问题描述】:

我一直在尝试让我的刷新令牌工作一段时间,我希望我已经接近了。我的令牌刷新并触发随后的 200 调用,无论调用什么导致 401,但我页面上的数据没有刷新。

当访问令牌过期时,会发生以下情况:

在 401 之后,GetListofCompanyNames 返回 200,其中包含使用正确更新的访问令牌的名称列表。但是,我的下拉菜单没有刷新。

我的拦截器:

  app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
        return {
            request: function(config) {

                config.headers = config.headers || {};

                var authData = localStorageService.get('authorizationData');
                if (authData) {
                    config.headers.Authorization = 'Bearer ' + authData.token;
                }
                return config;
            },
            responseError: function(rejection) {
                //var promise = $q.reject(rejection);
                var authService = $injector.get('authService');
                if (rejection.status === 401) {

                    // refresh the token
                    authService.refreshToken().then(function() {
                        // retry the request
                        var $http = $injector.get('$http');
                        return $http(rejection.config);
                    });
                }
                if (rejection.status === 400) {
                    authService.logOut();
                    $location.path('/login');
                }
                return $q.reject(rejection);
            }
        };
    }
]);

我关于 401 拒绝的返回声明在这里看起来很可疑,但我不确定用什么替换它。因此我的问题是:当我拨打新电话时,如何让我的页面刷新它的数据?

更新:

当 200 返回时,这让我过去了,我可以让下拉菜单刷新,但我会丢失页面上的任何状态(例如,选定的下拉菜单),如下所示。

authService.refreshToken().then(function() {
var $state = $injector.get('$state');
$state.reload();
});

回到绘图板!

【问题讨论】:

  • 你使用angularjs路由系统吗?
  • 是的,用户界面路由器:github.com/angular-ui/ui-router
  • 您是否尝试将 $state 服务注入您的authInterceptorService 并使用$state.reload()
  • @Julien 会这么简单吗?看起来像取消 return 语句并执行 state.reload 可能已经成功了。我已经坚持了一段时间,我会像使用 state.reload 一样运行它。有一次,我很满意它的工作原理(我不明白为什么不能),我很乐意接受你的建议作为答案!
  • @Julien 看起来好得令人难以置信,我可以在它空闲时使用 state.reload() 刷新我的下拉列表,但随后我在页面的工作流程中丢失了下拉列表在随后的基于 401 的重新加载中,需要重新启动工作流。

标签: asp.net angularjs oauth-2.0 jwt refresh-token


【解决方案1】:

我想你可能想改变你做这件事的方式。解决此问题的一种方法是将$rootScope 注入您的authInterceptorService,然后在成功刷新令牌后,调用$rootScope.broadcast('tokenRefreshed') 之类的东西。

我不太清楚您如何设置处理下拉列表的视图和控制器,但我会为 'tokenRefreshed' 事件设置一个侦听器。从这里,您可以再次致电GetListofCompanyNames。如果您这样做,您可以轻松控制并确保模型得到更新。

【讨论】:

    【解决方案2】:

    尝试在$timeout 中拨打重试电话,它应该可以工作。

    这是更新后的代码:

    app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
            return {
                request: function(config) {
    
                    config.headers = config.headers || {};
    
                    var authData = localStorageService.get('authorizationData');
                    if (authData) {
                        config.headers.Authorization = 'Bearer ' + authData.token;
                    }
                    return config;
                },
                responseError: function(rejection) {
                    //var promise = $q.reject(rejection);
                    var authService = $injector.get('authService');
                    if (rejection.status === 401) {
    
                        // refresh the token
                        authService.refreshToken().then(function() {
                            // retry the request
                      return $timeout(function() {
                            var $http = $injector.get('$http');
                            return $http(rejection.config);
                        }});
                    }
                    if (rejection.status === 400) {
                        authService.logOut();
                        $location.path('/login');
                    }
                    return $q.reject(rejection);
                }
            };
        }
    ]);
    

    $timeout 返回一个用返回的内容完成的承诺 从函数参数,所以我们可以方便地返回 $http 调用包含在 $timeout 中。

    谢谢。

    【讨论】:

      【解决方案3】:

      我的最终解决方案:

      app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
              var $http;
              var retryHttpRequest = function(config, deferred) {
                  $http = $http || $injector.get('$http');
                  $http(config).then(function(response) {
                          deferred.resolve(response);
                      },
                      function(response) {
                          deferred.reject(response);
                      });
              }
      
              return {
                  request: function(config) {
      
                      config.headers = config.headers || {};
      
                      var authData = localStorageService.get('authorizationData');
                      if (authData) {
                          config.headers.Authorization = 'Bearer ' + authData.token;
                      }
                      return config;
                  },
                  responseError: function(rejection) {
                      var deferred = $q.defer();
                      if (rejection.status === 401) {
                          var authService = $injector.get('authService');
                          authService.refreshToken().then(function() {
                                  retryHttpRequest(rejection.config, deferred);
                              },
                              function () {
                                  authService.logOut();
                                  $location.path('/login');
                                  deferred.reject(rejection);
                              });
                      } else {
                          deferred.reject(rejection);
                      }
                      return deferred.promise;
                  }
              };
          }
      ]);
      

      几乎从https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.Web/app/services/authInterceptorService.js复制了1对1。

      这个透明地处理所有请求并在必要时刷新它们。它会在刷新令牌过期时注销用户,并通过正确拒绝将错误传递给控制器​​。但是,它似乎不适用于多个飞行中的请求,当我在我的系统中获得它的用例时,我会研究它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-05
        • 2016-06-25
        • 1970-01-01
        • 1970-01-01
        • 2021-04-06
        • 2017-10-11
        • 2016-10-14
        • 2021-08-20
        相关资源
        最近更新 更多