AngularJS使用UI-Router解决身份验证问题

3

目前,我有一个简单的Angular设置,其中包含登录状态和云状态。我想让云状态只能在用户经过身份验证后运行。如果没有经过验证,它将引导他们到登录状态。

到目前为止,我相信我已经设置了“resolve”,并且我已经设置了.run()函数以在解析失败时重定向到登录状态。

我只是不知道如何使authenticated: authenticated获得我需要的内容。我知道我必须在某处创建一个authenticated函数,我只是不知道正确的方法。

我是Angular新手,如果有人有任何建议,我会非常感激。

var routerApp = angular.module('app', ['ui.router'])

.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('/cloud');

    $stateProvider

        .state('login', {
            url: '/login',
            templateUrl: "pages/templates/login.html"
        })

        .state('cloud', {
            url: '/cloud',
            templateUrl: "pages/templates/account.html",
            resolve: { authenticated: authenticated }
        })

})
.run(function ($rootScope, $state, $log) {
    $rootScope.$on('$stateChangeError', function () {
        $state.go('login');
    });
});

你实际上可以将你的函数放在同一个resolve块中,或者引用另一个服务。这有点密集,但会真正向你展示正确的方法:https://dev59.com/aGEh5IYBdhLWcg3wVCLK - cerd
@cerd 这有点超出我的能力范围。不过谢谢你提供的链接,这是我能找到的唯一一个例子。 - bryan
1个回答

8

关于 resolve,其实并不复杂,请查看文档:

解析

您可以使用 resolve 为状态提供特定于控制器的内容或数据。resolve 是一个可选的依赖项映射,应注入到控制器中。

如果这些依赖项中有任何 promise,则在实例化控制器和触发 $stateChangeSuccess 事件之前,它们将被解析并转换为值。

...

示例:

在实例化控制器之前,必须解决resolve中的每个对象(如果它们是promise,则通过deferred.resolve()进行解决)。请注意,每个resolve对象都作为参数注入到控制器中。

$stateProvider.state('myState', {
    resolve:{

       // Example using function with simple return value.
       // Since it's not a promise, it resolves immediately.
       simpleObj:  function(){
          return {value: 'simple!'};
       },
       ...

如果您需要一些工作的plunker,这里有类似的问题和答案:

如果我们想要实现DRY,我们应该开始考虑状态层次结构(父/子/...)。如此讨论:

我们可以引入一些超级“根”状态,用于一些通用目的:

$stateProvider
  .state('root', {
    abstract : true,
    // see controller def below
    controller : 'RootCtrl',
    // this is template, discussed below - very important
    template: '<div ui-view></div>',
    // resolve used only once, but for available for all child states
    resolve: {
      user: function (authService) {
          return authService.getUserDetails();
      }
    }
  }) 

那意味着,每个子状态都将获得已解决的祖先(“根”)的解决方案。如果我们想区分父级和子级解决方案,我们可以使用默认的解决方案名称...在这里查看详细信息:angular ui-route state parent and resolve (nested resolves)。如果我们还想解决拒绝,我们只需请求$state提供程序并重定向即可。最好的地方是某种类型的更改状态监听器。有一个详细的描述如何使用$rootScope.$on('$stateChangeStart',用于身份验证目的。Confusing $locationChangeSuccess and $stateChangeStart

谢谢你的详细回复,我很感激。如果有多个状态需要解决,我不想一遍又一遍地重复使用该函数。我的问题或多或少在于如何避免重复代码以及如何拒绝一个 Promise。 - bryan
我在我的答案中加入了更多细节,并包含了其他具有清晰和可工作的plunker的参考资料。我认为,这是您可以实现对UI-Router的“理解”的最佳方法。希望它能有所帮助 ;) - Radim Köhler
@bryan 你可以创建一个父状态,并将所有需要身份验证的状态作为该状态的子状态。这样,你只需向父状态添加 resolve 就可以了。 - Himanshu Mittal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接