几个不同的问题和一些不同的教程中都涉及到了这一点,但是我所遇到的所有以前的资源并没有完全解决问题。
http://client.foo
http://api.foo/login
logout
api.foo/status
ng-show="user.is_authenticated"
{{user.first_name}}
// Sample response from `/status` if successful { customer: {...}, is_authenticated: true, authentication_timeout: 1376959033, ... }
POST
post data
query params
withCredentials:true
诚然,我是Angular的新手,如果我以一种荒谬的方式来处理它,也不会感到惊讶。如果有人提出其他选择,我会很高兴-即使是汤到坚果。
我使用的Express主要是因为我真的很喜欢Jade和Stylus-我没有结婚的Express“路由和会放弃它,如果我想要做的是唯一可能与角的路由。
Express
Jade
Stylus
在此先感谢您提供任何帮助。而且请不要问我Google,因为我有大约26页的紫色链接。;-)
1该解决方案依赖于Angular的$ httpBackend模拟,并且尚不清楚如何使其与真实服务器对话。
2这是最接近的,但是由于我已有需要使用的API进行身份验证,因此无法使用护照的’localStrategy’,并且编写OAUTH服务似乎是 疯狂的 ……只有我打算使用。
这摘自我在此处有关url路由授权和元素安全性的博客文章,但我将简要总结要点:-)
前端Web应用程序中的安全性只是阻止Joe Public的开始措施,但是任何具有Web知识的用户都可以规避它,因此您也应该始终在服务器端拥有安全性。
角度安全性方面的主要关注点是路线安全性,幸运的是,在定义角度路线时,您要创建一个对象,该对象可以具有其他属性。我的方法的基础是在此路由对象中添加一个安全对象,该对象基本上定义了用户必须具有的角色才能访问特定路由。
// route which requires the user to be logged in and have the 'Admin' or 'UserManager' permission $routeProvider.when('/admin/users', { controller: 'userListCtrl', templateUrl: 'js/modules/admin/html/users.tmpl.html', access: { requiresLogin: true, requiredPermissions: ['Admin', 'UserManager'], permissionType: 'AtLeastOne' });
整个方法围绕授权服务进行,该服务基本上进行检查以查看用户是否具有所需的权限。该服务将关注点从该解决方案的其他部分中抽象出来,以解决用户及其在登录期间可能已从服务器检索到的实际许可。虽然代码很冗长,但我的博客文章中已对其进行了详细说明。但是,它基本上处理许可检查和两种授权模式。第一个是用户必须至少具有定义的权限中的一个,第二个是用户必须具有所有定义的权限。
angular.module(jcs.modules.auth.name).factory(jcs.modules.auth.services.authorization, [ 'authentication', function (authentication) { var authorize = function (loginRequired, requiredPermissions, permissionCheckType) { var result = jcs.modules.auth.enums.authorised.authorised, user = authentication.getCurrentLoginUser(), loweredPermissions = [], hasPermission = true, permission, i; permissionCheckType = permissionCheckType || jcs.modules.auth.enums.permissionCheckType.atLeastOne; if (loginRequired === true && user === undefined) { result = jcs.modules.auth.enums.authorised.loginRequired; } else if ((loginRequired === true && user !== undefined) && (requiredPermissions === undefined || requiredPermissions.length === 0)) { // Login is required but no specific permissions are specified. result = jcs.modules.auth.enums.authorised.authorised; } else if (requiredPermissions) { loweredPermissions = []; angular.forEach(user.permissions, function (permission) { loweredPermissions.push(permission.toLowerCase()); }); for (i = 0; i < requiredPermissions.length; i += 1) { permission = requiredPermissions[i].toLowerCase(); if (permissionCheckType === jcs.modules.auth.enums.permissionCheckType.combinationRequired) { hasPermission = hasPermission && loweredPermissions.indexOf(permission) > -1; // if all the permissions are required and hasPermission is false there is no point carrying on if (hasPermission === false) { break; } } else if (permissionCheckType === jcs.modules.auth.enums.permissionCheckType.atLeastOne) { hasPermission = loweredPermissions.indexOf(permission) > -1; // if we only need one of the permissions and we have it there is no point carrying on if (hasPermission) { break; } } } result = hasPermission ? jcs.modules.auth.enums.authorised.authorised : jcs.modules.auth.enums.authorised.notAuthorised; } return result; };
现在,路由已具有安全性,您需要一种确定路线更改开始后用户是否可以访问该路由的方法。为此,我们拦截了路由更改请求,检查了路由对象(上面有我们的新访问对象),如果用户无法访问视图,我们将其替换为另一个视图。
angular.module(jcs.modules.auth.name).run([ '$rootScope', '$location', jcs.modules.auth.services.authorization, function ($rootScope, $location, authorization) { $rootScope.$on('$routeChangeStart', function (event, next) { var authorised; if (next.access !== undefined) { authorised = authorization.authorize(next.access.loginRequired, next.access.permissions, next.access.permissionCheckType); if (authorised === jcs.modules.auth.enums.authorised.loginRequired) { $location.path(jcs.modules.auth.routes.login); } else if (authorised === jcs.modules.auth.enums.authorised.notAuthorised) { $location.path(jcs.modules.auth.routes.notAuthorised).replace(); } } }); }]);
这里的关键实际上是’.replace()’,因为它将当前路由(他们没有权限查看的路由)替换为我们将其重定向到的路由。这将停止任何操作,然后导航回未经授权的路线。
现在,我们可以拦截路由,我们可以做很多很酷的事情,包括如果用户登陆需要登录的路由,则在登录后进行重定向。
解决方案的第二部分是能够根据那里的权限向用户隐藏/显示UI元素。这可以通过一个简单的指令来实现。
angular.module(jcs.modules.auth.name).directive('access', [ jcs.modules.auth.services.authorization, function (authorization) { return { restrict: 'A', link: function (scope, element, attrs) { var makeVisible = function () { element.removeClass('hidden'); }, makeHidden = function () { element.addClass('hidden'); }, determineVisibility = function (resetFirst) { var result; if (resetFirst) { makeVisible(); } result = authorization.authorize(true, roles, attrs.accessPermissionType); if (result === jcs.modules.auth.enums.authorised.authorised) { makeVisible(); } else { makeHidden(); } }, roles = attrs.access.split(','); if (roles.length > 0) { determineVisibility(true); } } }; }]);
然后,您将确定像这样的元素:
<button type="button" access="CanEditUser, Admin" access-permission-type="AtLeastOne">Save User</button>
阅读我的完整博客文章,以详细了解该方法。