加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – angular ui-router登录身份验证

发布时间:2020-12-17 09:35:57 所属栏目:安全 来源:网络整理
导读:我是新的AngularJS,我有点困惑,如何我可以使用angular-“ui路由器”在以下场景: 我建立一个由两个部分组成的Web应用程序。第一部分是具有登录和注册视图的主页,第二部分是仪表板(成功登录后)。 我已经创建了一个index.html的主页部分,其角度应用程序和u
我是新的AngularJS,我有点困惑,如何我可以使用angular-“ui路由器”在以下场景:

我建立一个由两个部分组成的Web应用程序。第一部分是具有登录和注册视图的主页,第二部分是仪表板(成功登录后)。

我已经创建了一个index.html的主页部分,其角度应用程序和ui路由器配置来处理/ login和/ signup视图,
还有另一个文件dashboard.html用于仪表板部分及其应用程序和ui-router配置以处理许多子视图。

现在我完成了仪表板部分,不知道如何将这两个部分与他们不同的角度应用程序。如何让家庭应用重定向到信息中心应用?

我正在做一个更好的演示,以及清理一些这些服务成一个可用的模块,但这里是我想出了。这是一个复杂的过程,解决一些注意事项,所以挂在那里。你需要把它分成几部分。

Take a look at this plunk。

首先,您需要一个服务来存储用户的身份。我称之为校长。可以检查用户是否登录,并且根据请求,它可以解析表示关于用户身份的基本信息的对象。这可以是任何你需要的,但必要的将是显示名称,用户名,可能是电子邮件,和用户所属的角色(如果这适用于你的应用程序)。校长还有方法来做角色检查。

.factory('principal',['$q','$http','$timeout',function($q,$http,$timeout) {
    var _identity = undefined,_authenticated = false;

    return {
      isIdentityResolved: function() {
        return angular.isDefined(_identity);
      },isAuthenticated: function() {
        return _authenticated;
      },isInRole: function(role) {
        if (!_authenticated || !_identity.roles) return false;

        return _identity.roles.indexOf(role) != -1;
      },isInAnyRole: function(roles) {
        if (!_authenticated || !_identity.roles) return false;

        for (var i = 0; i < roles.length; i++) {
          if (this.isInRole(roles[i])) return true;
        }

        return false;
      },authenticate: function(identity) {
        _identity = identity;
        _authenticated = identity != null;
      },identity: function(force) {
        var deferred = $q.defer();

        if (force === true) _identity = undefined;

        // check and see if we have retrieved the 
        // identity data from the server. if we have,// reuse it by immediately resolving
        if (angular.isDefined(_identity)) {
          deferred.resolve(_identity);

          return deferred.promise;
        }

        // otherwise,retrieve the identity data from the
        // server,update the identity object,and then 
        // resolve.
        //           $http.get('/svc/account/identity',//                     { ignoreErrors: true })
        //                .success(function(data) {
        //                    _identity = data;
        //                    _authenticated = true;
        //                    deferred.resolve(_identity);
        //                })
        //                .error(function () {
        //                    _identity = null;
        //                    _authenticated = false;
        //                    deferred.resolve(_identity);
        //                });

        // for the sake of the demo,fake the lookup
        // by using a timeout to create a valid
        // fake identity. in reality,you'll want 
        // something more like the $http request
        // commented out above. in this example,we fake 
        // looking up to find the user is
        // not logged in
        var self = this;
        $timeout(function() {
          self.authenticate(null);
          deferred.resolve(_identity);
        },1000);

        return deferred.promise;
      }
    };
  }
])

其次,您需要一个检查用户想要访问的状态的服务,确保他们已登录(如果需要,无需登录,密码重置等),然后进行角色检查(如果您的应用程序需要这个)。如果它们未通过身份验证,请将其发送到登录页面。如果它们已通过身份验证,但未能通过角色检查,请将其发送到访问被拒绝页面。我叫这个服务授权。

.factory('authorization',['$rootScope','$state','principal',function($rootScope,$state,principal) {
    return {
      authorize: function() {
        return principal.identity()
          .then(function() {
            var isAuthenticated = principal.isAuthenticated();

            if ($rootScope.toState.data.roles
                && $rootScope.toState
                             .data.roles.length > 0 
                && !principal.isInAnyRole(
                   $rootScope.toState.data.roles))
            {
              if (isAuthenticated) {
                  // user is signed in but not
                  // authorized for desired state
                  $state.go('accessdenied');
              } else {
                // user is not authenticated. Stow
                // the state they wanted before you
                // send them to the sign-in state,so
                // you can return them when you're done
                $rootScope.returnToState
                    = $rootScope.toState;
                $rootScope.returnToStateParams
                    = $rootScope.toStateParams;

                // now,send them to the signin state
                // so they can log in
                $state.go('signin');
              }
            }
          });
      }
    };
  }
])

现在所有你需要做的是监听在ui路由器的$stateChangeStart.这让你有机会检查当前状态,他们想去的状态,并插入您的授权检查。如果失败,您可以取消路由转换,或更改到不同的路由。

.run(['$rootScope','$stateParams','authorization',$stateParams,authorization,principal)
{
      $rootScope.$on('$stateChangeStart',function(event,toState,toStateParams)
      {
        // track the state the user wants to go to; 
        // authorization service needs this
        $rootScope.toState = toState;
        $rootScope.toStateParams = toStateParams;
        // if the principal is resolved,do an 
        // authorization check immediately. otherwise,// it'll be done when the state it resolved.
        if (principal.isIdentityResolved()) 
            authorization.authorize();
      });
    }
  ]);

跟踪用户身份的棘手部分是:如果您已经验证(例如,您在上一个会话之后访问该网页,并在Cookie中保存了身份验证令牌,或者您可能已经刷新了某个网页,或者从链接删除到URL)。由于ui路由器的工作方式,您需要在您的身份验证检查之前进行一次身份验证。你可以使用状态配置中的resolve选项。我有一个父状态为所有状态继承的网站,这迫使委托人在任何事情发生之前解决。

$stateProvider.state('site',{
  'abstract': true,resolve: {
    authorize: ['authorization',function(authorization) {
        return authorization.authorize();
      }
    ]
  },template: '<div ui-view />'
})

这里有另一个问题…解决只被调用一次。一旦您的身份查询的承诺完成,它将不再运行解决委托。所以我们必须在两个地方进行你的验证检查:一次根据你的身份承诺解析,这覆盖了你的应用程序第一次加载,一次在$ stateChangeStart如果分辨率已经完成,这涵盖任何时候你导航状态。

好吧,到目前为止我们做了什么?

>我们会检查用户登录时应用加载的时间。
>我们跟踪登录用户的信息。
>我们将其重定向到需要用户登录的状态的登录状态。
>如果他们没有访问权限,我们将它们重定向到访问被拒绝状态。
>我们有一个机制,将用户重定向到他们请求的原始状态,如果我们需要他们登录。
>我们可以签出用户(需要与管理您的身份验证票据的任何客户端或服务器代码一起连接)。
>每当用户重新加载浏览器或关闭链接时,我们不需要将用户重新发送到登录页面。

我们从这里去哪里?那么,您可以将您的状态组织到需要登录的区域中。通过将角色的数据添加到这些状态(或者如果您要使用继承,则可以是这些状态的父级)来请求认证/授权用户。在这里,我们将资源限制为Admins:

.state('restricted',{
    parent: 'site',url: '/restricted',data: {
      roles: ['Admin']
    },views: {
      'content@': {
        templateUrl: 'restricted.html'
      }
    }
  })

现在你可以控制状态,用户可以访问一个路由。任何其他问题?也许只根据视图是否登录才改变视图的一部分?没问题。使用principal.isAuthenticated()或甚至principal.isInRole()与您有条件地显示模板或元素的许多方法中的任何一种。

首先,将principal注入控制器或其他任何东西,并将其粘贴到范围,以便您可以轻松地在您的视图中使用它:

.scope('HomeCtrl',['$scope',function($scope,principal)
{
  $scope.principal = principal;
});

显示或隐藏元素:

<div ng-show="principal.isAuthenticated()">
   I'm logged in
</div>
<div ng-hide="principal.isAuthenticated()">
  I'm not logged in
</div>

等等,等等,等等。无论如何,在您的示例应用程序中,您将有一个主页的状态,将允许未经身份验证的用户删除。它们可以包含指向登录或注册状态的链接,或者将那些表单内置到该页面中。无论适合你。

仪表板页面都可以从需要用户登录的状态继承,也就是说,可以是用户角色成员。我们讨论的所有授权都会从那里流出。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读