gpt4 book ai didi

javascript - AngularJS ui-router 登录认证

转载 作者:IT老高 更新时间:2023-10-28 11:02:53 25 4
gpt4 key购买 nike

我是 AngularJS 的新手,我对如何在以下场景中使用 angular-"ui-router"有点困惑:

我正在构建一个包含两个部分的 Web 应用程序。第一部分是主页及其登录和注册 View ,第二部分是仪表板(成功登录后)。

我创建了一个 index.html用于带有 angular 应用程序和 ui-router 的主页部分要处理的配置 /login/signup意见,
还有另一个文件 dashboard.html对于仪表板部分及其应用程序和 ui-router配置来处理许多 subview 。

现在我完成了仪表板部分,但不知道如何将这两个部分与不同的 angular 应用程序结合起来。我怎么能告诉家庭应用程序重定向到仪表板应用程序?

最佳答案

我正在制作一个更好的演示,并将其中的一些服务清理成一个可用的模块,但这是我想出的。这是解决一些警告的复杂过程,因此请坚持下去。你需要把它分解成几个部分。

Take a look at this plunk .

首先,您需要一个服务来存储用户的身份。我叫这个 principal .可以检查用户是否已登录,并且根据请求,它可以解析代表有关用户身份的基本信息的对象。这可以是您需要的任何内容,但基本要素是显示名称、用户名、可能是电子邮件以及用户所属的 Angular 色(如果这适用于您的应用)。 Principal 还具有进行 Angular 色检查的方法。

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

其次,您需要一个服务来检查用户想要进入的状态,确保他们已登录(如有必要;登录、密码重置等不需要),然后进行 Angular 色检查(如果您的应用需要这个)。如果它们未通过身份验证,请将它们发送到登录页面。如果它们已通过身份验证,但未能通过 Angular 色检查,请将它们发送到访问被拒绝页面。我叫这个服务 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();
});
}
]);

跟踪用户身份的棘手部分是在您已经通过身份验证的情况下查找它(例如,您在上一次 session 之后访问该页面,并将身份验证 token 保存在 cookie 中,或者您可能硬刷新了页面,或者从链接拖放到 URL 上)。因为路 ui-router有效,您需要在身份验证检查之前进行一次身份解析。您可以使用 resolve 执行此操作您的状态配置中的选项。我有一个站点的父状态,所有状态都从它继承,这迫使主体在发生任何其他事情之前得到解决。
$stateProvider.state('site', {
'abstract': true,
resolve: {
authorize: ['authorization',
function(authorization) {
return authorization.authorize();
}
]
},
template: '<div ui-view />'
})

这里还有一个问题... resolve只会被调用一次。一旦您的身份查找 promise 完成,它就不会再次运行解析委托(delegate)。因此,我们必须在两个地方进行您的身份验证检查:一次根据您的身份 promise 在 resolve 中解决。 ,包括第一次您的应用程序加载,一次在 $stateChangeStart如果决议已经完成,这涵盖了您在各州之间导航的任何时间。

好的,那么到目前为止我们做了什么?
  • 如果用户登录,我们会检查应用程序何时加载。
  • 我们跟踪有关登录用户的信息。
  • 对于需要用户登录的状态,我们将它们重定向到登录状态。
  • 如果他们没有访问权限,我们会将他们重定向到访问被拒绝状态。
  • 如果我们需要他们登录,我们有一种机制可以将用户重定向回他们请求的原始状态。
  • 我们可以将用户注销(需要与管理您的身份验证票证的任何客户端或服务器代码一致)。
  • 我们不需要在用户每次重新加载浏览器或点击链接时都将用户发送回登录页面。

  • 我们从这里去哪里?好吧,您可以将您的州组织成需要登录的区域。您可以通过添加 data 来要求经过身份验证/授权的用户。与 roles到这些状态(或它们的父级,如果您想使用继承)。在这里,我们将资源限制为管理员:
    .state('restricted', {
    parent: 'site',
    url: '/restricted',
    data: {
    roles: ['Admin']
    },
    views: {
    'content@': {
    templateUrl: 'restricted.html'
    }
    }
    })

    现在,您可以逐州控制哪些用户可以访问路线。还有其他顾虑吗?也许根据他们是否登录只改变 View 的一部分?没问题。使用 principal.isAuthenticated()甚至 principal.isInRole()使用多种方式中的任何一种,您都可以有条件地显示模板或元素。

    首先注入(inject) principal进入 Controller 或其他任何东西,并将其粘贴到范围内,以便您可以在 View 中轻松使用它:
    .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 Angular 色成员。我们讨论过的所有授权内容都将从那里流出。

    关于javascript - AngularJS ui-router 登录认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22537311/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com