栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

AngularJS UI路由器登录身份验证

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AngularJS UI路由器登录身份验证

我正在做一个更好的演示,并将其中的一些服务清理到一个可用的模块中,但这是我想出的。要解决一些警告,这是一个复杂的过程,所以请坚持。您需要将其分解为几部分。

看看这个pl。

首先,您需要一项服务来存储用户的身份。我叫这个

principal
。可以检查它是否查看用户是否登录,并且可以根据请求解析一个代表有关用户身份的基本信息的对象。这可以是您需要的任何内容,但必不可少的是显示名称,用户名(可能是电子邮件)以及用户所属的角色(如果适用于您的应用程序)。Principal还具有进行角色检查的方法。

.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;      }    };  }])

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

authorization

.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-router
$stateChangeStart
。这使您有机会检查当前状态,他们想进入的状态并插入授权检查。如果失败,则可以取消路由转换,或更改为其他路由。

.run(['$rootScope', '$state', '$stateParams',       'authorization', 'principal',    function($rootScope, $state, $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();      });    }  ]);

跟踪用户身份的棘手部分是如果您已通过身份验证,则查找该身份(例如,您在上一个会话之后访问该页面,并将auth令牌保存在cookie中,或者您可能很难刷新页面,或者从链接拖放到URL上)。由于这种方式

ui-router
有效,因此您需要在身份验证之前完成一次身份解析。您可以使用
resolve
状态配置中的选项来执行此操作。对于所有状态都继承自该站点的站点,我有一个父状态,这会迫使主体在发生其他任何事情之前先进行解析。

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

这里还有另一个问题…

resolve
只会被调用一次。一旦您完成对身份查询的承诺,就不会再运行解析委托。因此,我们必须在两个位置进行身份验证检查:一次是根据中的身份承诺解析
resolve
,这一次是应用程序首次加载;一次是
$stateChangeStart
在解决方案完成后,这一次遍历您浏览状态的时间。

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

  1. 如果用户已登录,我们将检查该应用何时加载。
  2. 我们跟踪有关登录用户的信息。
  3. 我们将它们重定向到需要用户登录的状态的登录状态。
  4. 如果他们无权访问它们,我们会将它们重定向到拒绝访问状态。
  5. 如果需要用户登录,我们有一种机制可以将用户重定向回他们请求的原始状态。
  6. 我们可以注销用户(需要与管理您的身份验证票的任何客户端或服务器代码保持一致)。
  7. 每当用户重新加载浏览器或断开链接时,我们 都不 需要将用户带回到登录页面。

我们从这里去哪里?嗯,你可以组织你的状态到需要的标志地区。您可以通过添加需要身份验证/授权用户

data
roles
这些国家(或他们的父母,如果你想使用继承)。在这里,我们将资源限制为管理员:

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

现在,您可以按状态控制哪些用户可以访问路由。还有其他问题吗?也许仅根据视图是否已登录来更改视图的一部分?没问题。可以使用,

principal.isAuthenticated()
甚至可以
principal.isInRole()
使用多种方式有条件地显示模板或元素。

首先,注入

principal
控制器或其他任何东西,并将其粘贴到示波器上,以便可以在视图中轻松使用它:

.scope('HomeCtrl', ['$scope', 'principal',     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>

等等,依此类推。无论如何,在示例应用程序中,您将拥有主页状态,该状态将使未经身份验证的用户掉队。他们可以具有指向登录或注册状态的链接,或者可以将那些表单内置到该页面中。任何适合您的。

仪表板页面都可以从要求用户登录并成为

User
角色成员的状态继承。我们已经讨论过的所有授权内容都将从那里流淌。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/633216.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号