gpt4 book ai didi

angularjs - 具有多个 Angular 色的 Angular SPA

转载 作者:行者123 更新时间:2023-12-03 08:02:59 39 4
gpt4 key购买 nike

我正在使用 Angular 1.5 构建一个 SPA,其中用户具有多个 Angular 色 [管理员、“查看所有内容”、“编辑特定内容”、基本用户]。我花了一整天的时间在谷歌上搜索,偶然发现了很多不同的解决方案,其中大多数似乎已经过时了。我的后端是 Slim 应用程序,使用 token 身份验证。

我的问题:如何为每个 Angular 色实现以不同方式显示相同的 ng-view?登录后后端应该返回我的 Angular 色和 token 吗?当用户尝试更改位置时,如何检查他是否已登录?我假设仅检查 token 是否存储在客户端上是不够的,因为我无法知道 token 何时过期?

我对基于 token 的身份验证和 Angular 真的很陌生。我不了解在我的案例中应该如何处理前端,而且我不知道从哪里开始。如果有任何答案、建议和提示可以帮助我理解应该做什么以及应该如何做,我将不胜感激。谢谢。

最佳答案

首先,使用UI-Router管理您的状态,即 url。

登录机制

成功登录后,您的后端必须返回一个访问 token ,但可能会也可能不会返回 Angular 色。但是您始终可以发送另一个请求来获取用户数据和 Angular 色并将它们保存到您的本地存储中。您可以创建服务,例如LoggedInUser 获取用户信息和 Angular 色。

angular
.module('myApp')
.factory('LoggedInUser', [
'$q',
'AppConfig',
'User',
function ($q,
AppConfig,
User) {

function getUser() {
var defer = $q.defer();
var userId = localStorage.getItem('$MyApp$userId');
var user = null;

var userStringified = localStorage.getItem('$MyApp$currentUser');
try {
user = JSON.parse(userStringified);
} catch (error) {
defer.reject(error);
}

if (user) {
defer.resolve(user);
} else {
User.findById({ // This is a server query
id: userId,
filter: {
include: 'roles'
}
})
.$promise
.then(function (userData) {
localStorage.setItem('$MyApp$currentUser', JSON.stringify(userData));
defer.resolve(userData);
}, function (error) {
defer.reject(error);
});
}

return defer.promise;
}

function clearUser() {
localStorage.removeItem('$MyApp$currentUser');
}

return {
getUser: getUser,
clearUser: clearUser
}

}]);

token 到期

您可以使用 Angular Interceptors拦截具有特定状态代码的服务器响应或您可以从服务器代码添加的任何自定义字段,例如code: 'TOKEN_EXPIRED' 响应对象,然后采取一些操作,例如注销用户或从拦截器发送另一个请求以获取另一个 token 以继续操作。

这取决于您的要求有多重要。在我的例子中,我可以显示一条消息,注销用户。

多重 Angular 色

处理多个 Angular 色对于前端和后端有不同的意义。

1。前端

在前端,限制分两层

1.1。到全图

您可能希望根据某些条件阻止状态处于事件状态,例如

  • 忘记密码页面应该只对未登录的用户可见,如果任何登录用户试图通过键入 url 访问,它应该重定向到他们的主页或仪表板页面。
  • 仪表板页面应该对具有任何 Angular 色的登录用户可见。
  • 列表用户页面应该对具有管理员 Angular 色的登录用户可见。

为了有这个限制,你需要 2 个数据项,一个是检查状态是否需要身份验证,另一个是检查该状态允许的 Angular 色。我正在使用具有 true/falseauthenticate 和具有允许 Angular 色数组的 allowedRoles。然后您可以在 $stateChangeStart 中使用它们事件。这是代码:

在你配置状态的一些js文件中:

$stateProvider
.state('home', {
abstract: true,
url: '',
templateUrl: 'app/home/home.html',
controller: 'HomeController',
resolve: {
loggedInUser: [
'LoggedInUser',
'$window',
'$q',
'User',
function (LoggedInUser,
$window,
$q,
User) {
var defer = $q.defer();
LoggedInUser.getUser()
.then(function (user) {
defer.resolve(user);
}, function (error) {
$window.alert('User is not authenticated.');
defer.reject(error);
});

return defer.promise;
}
]
},
data: {
authenticate: true
}
})
.state('home.dashboard', {
url: '/dashboard',
templateUrl: 'app/dashboard/dashboard.html',
controller: 'DashboardController',
data: {
roles: ['admin', 'basic-user']
}
})
.state('home.list-users', {
url: '/list-users',
templateUrl: 'app/users/list/list-users.html',
controller: 'ListUsersController',
data: {
roles: ['admin']
}
})
// More states

app.js中,run block

$rootScope.$on('$stateChangeStart', function (event, next, nextParams) {
var userLoggedIn = User.isAuthenticated();
/* If next state needs authentication and user is not logged in
* then redirect to login page.
*/
var authenticationRequired = (next.data && next.data.authenticate);
if (authenticationRequired) {
if (userLoggedIn) {
// Check role of logged in user and allowed roles of state to see if state is protected
var allowedRoles = next.data && next.data.roles;
if (allowedRoles && allowedRoles.length > 0) {
console.log('State access allowed to: ' + allowedRoles);
LoggedInUser.getUser()
.then(function (result) {
var allowed = false;
var user = result;
var role = user.role;
var allowed = (allowedRoles.indexOf(role) >= 0);
console.log(role + ' can access ' + allowed);

if (!allowed) {
var isAdministrator = user.isAdministrator;
if (isAdministrator) {
console.log('User is administrator: ' + isAdministrator);
role = 'administrator';
allowed = (allowedRoles.indexOf(role) >= 0);
console.log(role + ' can access ' + allowed);
}
}

if (!allowed) {
event.preventDefault(); //prevent current page from loading
$state.go('home.dashboard');
AppModalBox.show('danger', 'Not Authorized', 'You are not authorized to view this page.');
}
}, function (error) {
console.log(error);
});
}
} else {
event.preventDefault(); // Prevent current page from loading
$state.go('publicHome.auth.login');
}
} else {
/* This code block handles publicly accessible page like login, forgot password etc.
* Public states (pages) have redirectToLoggedInState data set to either true or false.
* redirectToLoggedInState set to true/false means that public page cannot/can be accessed by the logged in user.
*
* If user is logged in and any public state having redirectToLoggedInState data set to true
* then redirect to dashboard page and prevent opening page.
*/
var redirectToLoggedInState = (next.data && next.data.redirectToLoggedInState);
if (userLoggedIn && redirectToLoggedInState) {
event.preventDefault(); //prevent current page from loading
$state.go('home.dashboard');
}
}
});

Data defined on super state is available on child states so you can group all your private states (which needs authentication) under one state (In the above example, it is home) and put data.authenticate on super most state.

1.2。到 View 中的某些部分

为了有这个限制,你可以在你的 Controller 中使用相同的LoggedInUser服务或者在最超状态下使用解析loggedInUser。将 Angular 色附加到 $scope 并使用 ng-if 显示和隐藏基于 Angular 色的部分。

Resolves defined on the super most state are accessible in all child states.

代码如下:

angular.module('myApp')
.controller('DashboardController', [
'$scope',
'loggedInUser',
function ($scope,
loggedInUser) {

$scope.roles = loggedInUser.roles;

}]);

2。后端

您可以从 localStorage 获取访问 token ,您必须在成功登录时保存它,并在每个请求中传递它。在后端,解析请求以检索访问 token ,获取此访问 token 的用户 ID,获取用户的 Angular 色,并检查是否允许具有这些 Angular 色的用户执行操作(如查询)。

我正在使用 NodeJS - ExpressJS,其中中间件用于处理此类基于 Angular 色的身份验证。

关于angularjs - 具有多个 Angular 色的 Angular SPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43670724/

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