【问题标题】:locationChangeStart and preventing route changelocationChangeStart 和防止路线改变
【发布时间】:2013-12-25 12:11:09
【问题描述】:

我正在尝试创建用户是否可以访问某些路由的基本验证。 我在这方面取得了进展,但有一件事我无法弄清楚。

我正在使用 $locationChangeStart 来监控路线变化。场景是: 1. 如果用户已登录,则允许他访问所有路由,除了 auth 路由(登录、注册)。我通过从我的 AuthFactory 调用方法 isAuthenticated() 来检查这个 2. 如果用户没有登录,那么他只能访问登录和注册路由。应阻止任何其他路由,在这种情况下应将用户重定向到登录。

$rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl){
  if(AuthFactory.isAuthenticated()){
    if(AuthFactory.isAuthRoute(newUrl)){
      event.preventDefault();
      $location.path('/');
    }
  } else {
    if(!AuthFactory.isAuthRoute(newUrl)){
      event.preventDefault();
      $location.path('/login');
    }

  }
});

困扰我的是使用 preventDefault() 的事情。如果应用程序使用 preventDefault() 到达代码,那么之后的 location.path() 将无法正常工作。

但是,如果我删除 event.preventDefault()location.path() 会起作用。问题在于,我需要阻止,以防非登录尝试访问某些非身份验证页面。

基本上,我希望能够根据请求的路线阻止或重定向。这样做的正确方法是什么?

【问题讨论】:

  • 我不确定你在做什么以及你想要什么。你能给我们提供一个plunkr吗?
  • 嘿,爸爸,我编辑了我的问题,请检查现在是否更简洁?
  • 在我看来,你不应该使用 $location 服务。太低级了。我会检查github.com/angular-ui/ui-router,它更适合您描述的任务。
  • 我明白了,只是我认为我可以通过仅使用角度事件来管理它。我去看看,谢谢
  • 您是否尝试在 preventDefault() 之后使用 $timeout 触发 $location.path()。这样,您可以将事件中路径更改的取消和设置新路径分开。应该工作。

标签: angularjs authentication url-redirection angularjs-routing angularjs-authentication


【解决方案1】:

好的,你需要这样做:

var authPreventer = $rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl){
    if(AuthFactory.isAuthenticated()){
        if(AuthFactory.isAuthRoute(newUrl)){
            event.preventDefault();
            authPreventer(); //Stop listening for location changes
            $location.path('/');
        }
    } 
    else {
        if(!AuthFactory.isAuthRoute(newUrl)){
            event.preventDefault();
            authPreventer(); //Stop listening for location changes
            $location.path('/login');
        }
    }
});

【讨论】:

  • 为了记录,该博客文章看起来像是通过翻译器翻译成另一种语言并返回到英语。 sysmagazine 剽窃的原始帖子在这里:weblogs.asp.net/dwahlin/…
【解决方案2】:

您可以尝试在解析中使用 auth 以防止访问某些路由。 here 是文档,不是很清楚,但是你可以找到很多例子。

【讨论】:

  • 嘿yotamsha,没错,但是我需要附加resolve 并检查每条现有的和新的书面路线。我希望我在一个地方做,我的用例很常见,这就是为什么我不敢相信这很难做到,但看起来是这样 :) 感谢您的帮助!
【解决方案3】:

我最近遇到了同样的问题,我终于能够通过收听$routeChangeStart而不是$locationChangeStart来解决它(无需致电$route.reload())。

这两个事件的文档有点模糊......我想$ruteChangeStart 事件在$locationChangeStart 之前被调用(我将阅读源代码以完全理解这里发生的事情)。

【讨论】:

    【解决方案4】:

    好的,我设法使用 $routeChangeStart 做到了这一点。问题在于使用 $route.reload()。所以上面的代码应该是这样的:

    $rootScope.$on('$routeChangeStart', function(event, next, current){
      if(AuthFactory.isAuthenticated()){
        if(AuthFactory.isAuthRoute(next.originalPath)){
          $route.reload();
          $location.path('/');
        }       
      } else {
        if(!AuthFactory.isAuthRoute(next.originalPath)){
          $route.reload();
          $location.path('/login');
        }
      }
    });
    

    我把它放在我的 .run 方法中,所以所有的请求都在这里处理,我不需要考虑我(或其他人添加的)每条新路由。这就是为什么这对我来说看起来更干净。
    如果有人有不同的方法,请分享。

    注意:以防万一,我也会检查后端部分:)

    【讨论】:

    • 控制器仍会被调用,因此您实际上是在路由开始更改后更改路由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多