AngularJS:如何使用 UI-Router 的 Transition Hooks 从 API 检查授权?

AngularJS: How to check auth from API using Transition Hooks of UI-Router?

如何让转换挂钩等待来自我的 API 的 checkAuth() 请求失败,然后它会在转换挂钩未成功解析的情况下将用户重定向到登录页面?

这是我的转换钩子代码:

app.js

angular.module('app')
  .run(function ($state, $transitions, AuthService) {
    $transitions.onBefore({ to: 'auth.**' }, function() {
      AuthService.isAuthenticated().then(function (isAuthenticated) {
        if (!isAuthenticated) {
          $state.go('login');
        }
      });
    });
  });

我正在使用 $state 服务在未经身份验证的用户尝试访问授权受限视图时将用户重定向到登录页面。但是通过此实现,转换 onBefore() 已经解决,因此转换在我的 checkAuth() 方法完成之前成功。所以它仍然会显示它要去 (split) 秒的视图,然后再转换到登录视图。

下面是上面代码中使用的认证服务方法的实现:

auth.service.js

authService.isAuthenticated = function () {
  // Checks if there is an authenticated user in the app state.
  var authUser = AuthUserStore.get();
  if (authUser) {
    return Promise.resolve(true);
  }
  // Do check auth API request when there's no auth user in the app state.
  return authService.checkAuth()
    .then(function () {
        return !!AuthUserStore.get();
      });
};

authService.checkAuth = function () {
  return $http.get(API.URL + 'check-auth')
    .then(function (res) {
        // Store the user session data from the API.
        AuthUserStore.set(res.data);
        return res;
      });
};

根据我对 onBefore 钩子的理解,

The return value can be used to pause, cancel, or redirect the current Transition.

https://ui-router.github.io/ng1/docs/latest/classes/transition.transitionservice.html#onbefore

也许您需要查看 HookResult 并使用它来满足您的需要。

https://ui-router.github.io/ng1/docs/latest/modules/transition.html#hookresult

希望这对您有所帮助

干杯!

感谢 Jonathan Dsouza 提供来自 UI 路由器的 HookResult 文档。

此问题已通过处理来自 isAuthenticated() 服务方法的 Promise 解决,并返回必要的 HookResult 值以根据需要处理转换:

app.js

angular.module('app')
  .run(function ($transitions, AuthService) {
    $transitions.onBefore({to: 'auth.**'}, function (trans) {
      return AuthService.isAuthenticated().then(function (isAuthenticated) {
          if (!isAuthenticated) {
            return trans.router.stateService.target('login');
          }
          return true;
        });
    });
 });