首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ui-路由器StateChange事件甚至可以通过重定向完成。

ui-路由器StateChange事件甚至可以通过重定向完成。
EN

Stack Overflow用户
提问于 2015-04-14 00:24:39
回答 2查看 5.7K关注 0票数 0

我正在开发一个OAuth提供者应用程序,使用AngularJS和ui路由器.对于每个状态更改,我执行以下检查:

  1. 如果用户已经登录: 1.1如果用户不是管理->,如果用户是管理员,则将其重定向到callBackUrl 1.2,什么也不做
  2. 如果用户没有登录: 2.1如果用户试图访问管理页面,->将他重定向回登录2.2,如果没有,什么也不做

我的ui-路由器运行方法如下:

代码语言:javascript
复制
.run(function ($rootScope, $state, $auth, accountService, $window, $stateParams) {
    $rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
        accountService.getUser({ token: $auth.getToken() }).$promise
            .then(function (response) {
                if (response.isAdmin === false) {
                    e.preventDefault();
                    $window.location.href = $stateParams.callBackUrl;
                    return;
                }
            })
            .catch(function (response) {
                if (toState.name.split(".")[0] === 'admin') {
                    e.preventDefault();
                    $state.go('root.login');
                }
            });
    });
});

一切正常,除了我使用$window将用户重定向到回调URL的部分

代码语言:javascript
复制
$window.location.href = $stateParams.callBackUrl;

这个重定向需要2-3秒,同时我的用户可以看到他试图在我的应用程序上访问的页面。我认为使用preventDefault()可以解决这个问题,但它不能解决这个问题。您知道我如何保持$statechangeevent,以便将用户直接重定向到回调URL吗?

谢谢

EN

回答 2

Stack Overflow用户

发布于 2015-04-14 05:12:45

我会这样说:

上面的方法允许用户一切,直到他没有被证明是真正的身份验证。为什么要这样?因为代码正在调用服务和,因此一旦接收到数据,就会对所有内容进行评估。同时-我们相信用户。

所以,我建议改变这个方法

永远不要相信用户。他/她必须尽最大努力证明他/她是正确的人,去某个地方.(嗯,有点.)

我在这里描述了一种可能的方法(使用示例):

Confusing $locationChangeSuccess and $stateChangeStart

只是一段值得引用的代码

$rootScope.$on('$stateChangeStart', ...的第一部分

代码语言:javascript
复制
    // if already authenticated...
    var isAuthenticated = userService.isAuthenticated();
    // any public action is allowed
    var isPublicAction = angular.isObject(toState.data)
                       && toState.data.isPublic === true;    


    // here - user has already proved that he is the one
    // or the target is public (e.g. login page)
    // let him go, get out of this check

    if (isPublicAction || isAuthenticated) {
      return;
    }

第二部分,用户不受信任,他需要访问私有的东西。

代码语言:javascript
复制
    // now - stop everything
    // NO navigation
    // we have to be sure who user is, to continue

    // stop state change
    event.preventDefault();

    // async load user 
    userService
       .getAuthObject()
       .then(function (user) {

          var isAuthenticated = user.isAuthenticated === true;

          if (isAuthenticated) {
            // let's continue, use is allowed
            $state.go(toState, toParams)
            return;
          }    
          // log on / sign in...
          $state.go("login");
       })

检查一下,在行动中,here

票数 2
EN

Stack Overflow用户

发布于 2015-11-30 17:56:10

我知道这是不久前提出的,但这里有一个可能的解决办法:

Ui-路由器实际上提供了一种解决这个问题的极好方法。通过在$stateProvider中使用“解析”,您可以在该特定状态的控制器实例化之前检查用户是否经过身份验证。以下是ui-路由器文档对解析的看法:

解析 您可以使用resolve为控制器提供自定义状态的内容或数据。resolve是一个可选的依赖映射,应该注入到控制器中。 如果这些依赖项中有任何一个是承诺的,则在控制器实例化并触发$stateChangeSuccess事件之前,它们将被解析并转换为值$stateChangeSuccess。

https://github.com/angular-ui/ui-router/wiki -用于resolve的部分几乎是下半页

您可以在决心范围内运行accountService.getUser,以检查是否有经过身份验证的用户,这样做将防止未创建的人看到他们试图路由到的视图。

该解决方案是在$stateProvider中设置的,可能如下所示:

代码语言:javascript
复制
$stateProvider.state('myState', {
  resolve: {
    userAuth: function(accountService) {
      return accountService.getUser();
    }
  }
)

如果您注意到在上面的示例中,我在解析中设置了一个名为userAuth的属性。现在可以将它注入到任何控制器或服务中,然后您可以为经过身份验证的用户检查它。每个需要“受保护”视图的状态都可以包含解析,然后视图的2-3秒闪光灯就不会发生,因为控制器还没有被实例化,用户被重定向到另一个状态。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29617183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档