加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

AngularJS 应用身份认证的技巧总结

发布时间:2016-11-25 17:12:23 所属栏目:教程 来源:网络整理
导读:在web中很多时候都能应用到身份认证,本文介绍了AngularJS 应用身份认证的技巧,废话不多说了一起往下看吧。 身份认证 最普遍的身份认证方式就是用用户名(或 email)和密码做登陆操作。这就意味要实现一个登陆的表单,以便用户能够用他们个人信息登陆。这

在web中很多时候都能应用到身份认证,本文介绍了AngularJS 应用身份认证的技巧,废话不多说了一起往下看吧。

身份认证

最普遍的身份认证方式就是用用户名(或 email)和密码做登陆操作。这就意味要实现一个登陆的表单,以便用户能够用他们个人信息登陆。这个表单看起来是这样的:

lt;form name="loginForm" ng-controller="LoginController"
   ng-submit="login(credentials)" novalidategt;
 lt;label for="username"gt;Username:lt;/labelgt;
 lt;input type="text" id="username"
     ng-model="credentials.username"gt;
 lt;label for="password"gt;Password:lt;/labelgt;
 lt;input type="password" id="password"
     ng-model="credentials.password"gt;
 lt;button type="submit"gt;Loginlt;/buttongt;
lt;/formgt;

既然这个是 Angular-powered 的表单,我们使用 ngSubmit 指令去触发上传表单时的函数。注意一点的是,我们把个人信息传入到上传表单的函数,而不是直接使用 $scope.credentials 这个对象。这样使得函数更容易进行 unit-test 和降低这个函数与当前 Controller 作用域的耦合。这个 Controller 看起来是这样的:

.controller('LoginController', function ($scope, $rootScope, AUTH_EVENTS, AuthService) {
 $scope.credentials = {
  username: '',
  password: ''
 };
 $scope.login = function (credentials) {
  AuthService.login(credentials).then(function (user) {
   $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
   $scope.setCurrentUser(user);
  }, function () {
   $rootScope.$broadcast(AUTH_EVENTS.loginFailed);
  });
 };javascript:void(0);
})

我们注意到这里是缺少实际的逻辑的。这个 Controller 被做成这样,目的是使身份认证的逻辑跟表单解耦。把逻辑尽可能的从我们的 Controller 里面抽离出来,把他们都放到 services 里面,这是个很好的想法。AngularJS 的 Controller 应该只管理 $scope 里面的对象(用 watching 或者 手动操作)而不是承担过多过分重的东西。

通知 Session 的变化

身份认证会影响整个应用的状态。基于这个原因我更推荐使用事件(用 $broadcast)去通知 user session 的改变。把所有可能用到的事件代码定义在一个中间地带是个不错的选择。我喜欢用 constants 去做这个事情:

.constant('AUTH_EVENTS', {
 loginSuccess: 'auth-login-success',
 loginFailed: 'auth-login-failed',
 logoutSuccess: 'auth-logout-success',
 sessionTimeout: 'auth-session-timeout',
 notAuthenticated: 'auth-not-authenticated',
 notAuthorized: 'auth-not-authorized'
})

constants 有个很好的特性就是他们能随便注入到别的地方,就像 services 那样。这样使得 constants 很容易被我们的 unit-test 调用。constants 也允许你很容易地在随后对他们重命名而不需要改一大串文件。同样的戏法运用到了 user roles:

.constant('USER_ROLES', {
 all: '*',
 admin: 'admin',
 editor: 'editor',
 guest: 'guest'
})

如果你想给予 editors 和 administrators 同样的权限,你只需要简单地把 ‘editor' 改成 ‘admin'。

The AuthService

与身份认证和授权(访问控制)相关的逻辑最好被放到同一个 service:

.factory('AuthService', function ($http, Session) {
 var authService = {};

 authService.login = function (credentials) {
  return $http
   .post('/login', credentials)
   .then(function (res) {
    Session.create(res.data.id, res.data.user.id,
            res.data.user.role);
    return res.data.user;
   });
 };

 authService.isAuthenticated = function () {
  return !!Session.userId;
 };

 authService.isAuthorized = function (authorizedRoles) {
  if (!angular.isArray(authorizedRoles)) {
   authorizedRoles = [authorizedRoles];
  }
  return (authService.isAuthenticated() 
   authorizedRoles.indexOf(Session.userRole) !== -1);
 };
 return authService;
})

为了进一步远离身份认证的担忧,我使用另一个 service(一个单例对象,using the service style)去保存用户的 session 信息。session 的信息细节是依赖于后端的实现,但是我还是给出一个较普遍的例子吧:

.service('Session', function () {
 this.create = function (sessionId, userId, userRole) {
  this.id = sessionId;
  this.userId = userId;
  this.userRole = userRole;
 };
 this.destroy = function () {
  this.id = null;
  this.userId = null;
  this.userRole = null;
 };
 return this;
})

一旦用户登录了,他的信息应该会被展示在某些地方(比如右上角用户头像什么的)。为了实现这个,用户对象必须要被 $scope 对象引用,更好的是一个可以被全局调用的地方。虽然 $rootScope 是显然易见的第一个选择,但是我尝试克制自己,不过多地使用 $rootScope(实际上我只在全局事件广播使用 $rootScope)。用我所喜欢的方式去做这个事情,就是在应用的根节点,或者在别的至少高于 Dom 树的地方,定义一个 controller 。 标签是个很好的选择:

lt;body ng-controller="ApplicationController"gt;
 ...
lt;/bodygt;

ApplicationController 是应用的全局逻辑的容器和一个用于运行 Angular 的 run 方法的选择。因此它要处于 $scope 树的根,所有其他的 scope 会继承它(除了隔离 scope)。这是个很好的地方去定义 currentUser 对象:

.controller('ApplicationController', function ($scope,
                        USER_ROLES,
                        AuthService) {
 $scope.currentUser = null;
 $scope.userRoles = USER_ROLES;
 $scope.isAuthorized = AuthService.isAuthorized;

 $scope.setCurrentUser = function (user) {
  $scope.currentUser = user;
 };
})

(编辑:应用网_丽江站长网)

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

热点阅读