Heim >Web-Frontend >js-Tutorial >Implementierung von Funktionen zur Identitätsauthentifizierung und Formularüberprüfung für den Benutzerzugriff in AngularJS_AngularJS

Implementierung von Funktionen zur Identitätsauthentifizierung und Formularüberprüfung für den Benutzerzugriff in AngularJS_AngularJS

WBOY
WBOYOriginal
2016-05-16 15:04:391412Durchsuche

Pengesahan
Reka bentuk kebenaran yang paling biasa ialah kawalan akses berasaskan peranan RBAC Idea asas ialah pelbagai kebenaran untuk operasi sistem tidak diberikan secara langsung kepada pengguna tertentu, tetapi set peranan ditetapkan antara set pengguna dan set kebenaran . Setiap peranan sepadan dengan set kebenaran yang sepadan.
Setelah pengguna diberikan peranan yang sesuai, pengguna mempunyai semua kebenaran operasi peranan ini. Kelebihan ini ialah anda tidak perlu memberikan kebenaran setiap kali anda membuat pengguna Anda hanya perlu menetapkan peranan yang sepadan kepada pengguna Selain itu, perubahan kebenaran peranan adalah lebih rendah daripada perubahan kebenaran pengguna. yang akan memudahkan pengurusan kebenaran dan mengurangkan overhed sistem.
Dalam aplikasi satu halaman yang dibina oleh Angular, kami perlu melakukan beberapa perkara tambahan untuk melaksanakan seni bina sedemikian Dari segi keseluruhan projek, terdapat kira-kira tiga tempat yang perlu ditangani oleh jurutera hadapan 1. Pemprosesan UI (tentukan sama ada sesetengah kandungan pada halaman dipaparkan berdasarkan kebenaran yang dimiliki pengguna)
2. Pemprosesan penghalaan (apabila pengguna mengakses URL yang dia tidak mempunyai kebenaran untuk mengakses, lompat ke halaman ralat)
3. Pemprosesan permintaan HTTP (apabila kami menghantar permintaan data, jika status yang dikembalikan ialah 401 atau 403, ia biasanya diubah hala ke halaman ralat)

Pelaksanaan kawalan identiti akses
Mula-mula, kita perlu mendapatkan semua kebenaran pengguna semasa sebelum Angular bermula, dan kemudian cara yang lebih elegan ialah menyimpan hubungan pemetaan ini melalui perkhidmatan Untuk pemprosesan UI sama ada kandungan pada halaman dipaparkan mengikut kebenaran , kita harus menggunakan Arahan dilaksanakan Selepas memprosesnya, kita juga perlu menambahkan atribut "kebenaran" tambahan padanya apabila menambah laluan dan menetapkan nilai untuk menunjukkan peranan yang mempunyai kebenaran untuk melompat ke URL ini, dan kemudian mendengar. ke acara routeChangeStart melalui Angular Untuk mengesahkan sama ada pengguna semasa mempunyai hak akses ke URL ini Akhirnya, pemintas HTTP diperlukan untuk memantau apabila status dikembalikan oleh permintaan ialah 401 atau 403, dan melompat ke halaman ralat kerja itu kelihatan seperti banyak, tetapi ia sebenarnya agak mudah untuk dikendalikan satu persatu Kembalikan 401, laksanakan loginCtrl, kembali 403, laksanakan PermissionCtrl.

Dapatkan hubungan pemetaan kebenaran sebelum Angular dijalankan
Projek Angular dimulakan melalui ng-app, tetapi dalam beberapa kes kami mahukan permulaan projek Angular berada di bawah kawalan kami Contohnya, dalam kes ini, saya berharap untuk mendapatkan semua perhubungan pemetaan kebenaran pengguna yang sedang log masuk , dan kemudian Mulakan Apl Sudut Nasib baik, Angular sendiri menyediakan kaedah ini, iaitu angular.bootstrap().

var permissionList; 
angular.element(document).ready(function() { 
 $.get('/api/UserPermission', function(data) { 
 permissionList = data; 
 angular.bootstrap(document, ['App']); 
 }); 
}); 
Mereka yang melihat dengan teliti mungkin menyedari bahawa $.get() digunakan di sini adalah betul untuk menggunakan jQuery dan bukannya $sumber Angular atau $http, kerana Angular belum dimulakan pada masa ini belum.
Selanjutnya menggunakan kod di atas, anda boleh meletakkan hubungan pemetaan yang diperolehi ke dalam perkhidmatan dan menggunakannya sebagai pembolehubah global.


// app.js 
var app = angular.module('myApp', []), permissionList; 
 
app.run(function(permissions) { 
 permissions.setPermissions(permissionList) 
}); 
 
angular.element(document).ready(function() { 
 $.get('/api/UserPermission', function(data) { 
 permissionList = data; 
 angular.bootstrap(document, ['App']); 
 }); 
}); 
 
// common_service.js 
angular.module('myApp') 
 .factory('permissions', function ($rootScope) { 
 var permissionList; 
 return { 
  setPermissions: function(permissions) { 
  permissionList = permissions; 
  $rootScope.$broadcast('permissionsChanged') 
  } 
 }; 
 }); 
Selepas mendapatkan set kebenaran pengguna semasa, kami mengarkibkan set ini ke dalam perkhidmatan yang sepadan, dan kemudian melakukan dua perkara lagi:
(1) Simpan kebenaran dalam pembolehubah kilang supaya ia kekal dalam ingatan untuk mencapai peranan pembolehubah global tanpa mencemarkan ruang nama.

(2) Siarkan acara melalui $broadcast apabila kebenaran berubah.


1. Cara menentukan sama ada komponen UI kelihatan atau tersembunyi berdasarkan kebenaran
Di sini kita perlu menulis arahan sendiri, yang akan memaparkan atau menyembunyikan elemen berdasarkan perhubungan kebenaran

<!-- If the user has edit permission the show a link --> 
<div has-permission='Edit'> 
 <a href="/#/courses/{{ id }}/edit"> {{ name }}</a> 
</div> 
 
<!-- If the user doesn't have edit permission then show text only (Note the "!" before "Edit") --> 
<div has-permission='!Edit'> 
 {{ name }} 
</div> 
Di sini kita melihat bahawa situasi yang ideal adalah untuk lulus atribut mempunyai kebenaran untuk mengesahkan nama kebenaran Jika pengguna semasa mempunyai satu, ia akan dipaparkan, jika tidak, ia akan disembunyikan

Kembangkan kilang sebelumnya:
angular.module('myApp').directive('hasPermission', function(permissions) { 
 return { 
 link: function(scope, element, attrs) { 
  if(!_.isString(attrs.hasPermission)) 
  throw "hasPermission value must be a string"; 
 
  var value = attrs.hasPermission.trim(); 
  var notPermissionFlag = value[0] === '!'; 
  if(notPermissionFlag) { 
  value = value.slice(1).trim(); 
  } 
 
  function toggleVisibilityBasedOnPermission() { 
  var hasPermission = permissions.hasPermission(value); 
 
  if(hasPermission && !notPermissionFlag || !hasPermission && notPermissionFlag) 
   element.show(); 
  else 
   element.hide(); 
  } 
  toggleVisibilityBasedOnPermission(); 
  scope.$on('permissionsChanged', toggleVisibilityBasedOnPermission); 
 } 
 }; 
}); 

angular.module('myApp') 
 .factory('permissions', function ($rootScope) { 
 var permissionList; 
 return { 
  setPermissions: function(permissions) { 
  permissionList = permissions; 
  $rootScope.$broadcast('permissionsChanged') 
  }, 
  hasPermission: function (permission) { 
  permission = permission.trim(); 
  return _.some(permissionList, function(item) { 
   if(_.isString(item.Name)) 
   return item.Name.trim() === permission 
  }); 
  } 
 }; 
 }); 
2. Akses berdasarkan kebenaran pada laluan

Idea untuk melaksanakan bahagian ini adalah seperti berikut: Apabila kami menentukan laluan, tambahkan atribut kebenaran Nilai atribut ialah kebenaran untuk mengakses url semasa acara routeChangeStart Setiap kali url berubah Bila , semak sama ada url semasa yang hendak dilompat memenuhi syarat, dan kemudian tentukan sama ada untuk melompat dengan jayanya atau melompat ke halaman gesaan yang salah

mainController.js atau indexController.js (pendek kata, pengawal induk)
app.config(function ($routeProvider) { 
 $routeProvider 
 .when('/', { 
  templateUrl: 'views/viewCourses.html', 
  controller: 'viewCoursesCtrl' 
 }) 
 .when('/unauthorized', { 
  templateUrl: 'views/error.html', 
  controller: 'ErrorCtrl' 
 }) 
 .when('/courses/:id/edit', { 
  templateUrl: 'views/editCourses.html', 
  controller: 'editCourses', 
  permission: 'Edit' 
 }); 
}); 

这里依然用到了之前写的hasPermission,这些东西都是高度可复用的.这样就搞定了,在每次view的route跳转前,在父容器的Controller中判断一些它到底有没有跳转的权限即可.

3.HTTP请求处理
    这个应该相对来说好处理一点,思想的思路也很简单.因为Angular应用推荐的是RESTful风格的借口,所以对于HTTP协议的使用很清晰.对于请求返回的status code如果是401或者403则表示没有权限,就跳转到对应的错误提示页面即可.
    当然我们不可能每个请求都去手动校验转发一次,所以肯定需要一个总的filter.代码如下:

angular.module('myApp') 
 .config(function($httpProvider) { 
 $httpProvider.responseInterceptors.push('securityInterceptor'); 
 }) 
 .provider('securityInterceptor', function() { 
 this.$get = function($location, $q) { 
  return function(promise) { 
  return promise.then(null, function(response) { 
   if(response.status === 403 || response.status === 401) { 
   $location.path('/unauthorized'); 
   } 
   return $q.reject(response); 
  }); 
  }; 
 }; 
 }); 

写到这里就差不多可以实现在这种前后端分离模式下,前端部分的权限管理和控制了。


表单验证
AngularJS 前端验证指令

var rcSubmitDirective = { 
 'rcSubmit': function ($parse) { 
 return { 
  restrict: "A", 
  require: [ "rcSubmit", "&#63;form" ], 
  controller: function() { 
  this.attempted = false; 
  var formController = null; 
  this.setAttempted = function() { 
   this.attempted = true; 
  }; 
  this.setFormController = function(controller) { 
   formController = controller; 
  }; 
  this.needsAttention = function(fieldModelController) { 
   if (!formController) return false; 
   if (fieldModelController) { 
   return fieldModelController.$invalid && (fieldModelController.$dirty || this.attempted); 
   } else { 
   return formController && formController.$invalid && (formController.$dirty || this.attempted); 
   } 
  }; 
  }, 
  compile: function() { 
  return { 
   pre: function(scope, formElement, attributes, controllers) { 
   var submitController = controllers[0]; 
   var formController = controllers.length > 1 &#63; controllers[1] : null; 
   submitController.setFormController(formController); 
   scope.rc = scope.rc || {}; 
   scope.rc[attributes.name] = submitController; 
   }, 
   post: function(scope, formElement, attributes, controllers) { 
   var submitController = controllers[0]; 
   var formController = controllers.length > 1 &#63; controllers[1] : null; 
   var fn = $parse(attributes.rcSubmit); 
   formElement.bind("submit", function(event) { 
    submitController.setAttempted(); 
    if (!scope.$$phase) scope.$apply(); 
    if (!formController.$valid) return; 
    scope.$apply(function() { 
    fn(scope, { 
     $event: event 
    }); 
    }); 
   }); 
   } 
  }; 
  } 
 }; 
 } 
}; 

 
验证通过

<form name="loginForm" novalidate 
  ng-app="LoginApp" ng-controller="LoginController" rc-submit="login()"> 
 <div class="form-group" 
   ng-class="{'has-error': rc.loginForm.needsAttention(loginForm.username)}"> 
  <input class="form-control" name="username" type="text" 
    placeholder="Username" required ng-model="session.username" /> 
  <span class="help-block" 
    ng-show="rc.form.needsAttention(loginForm.username) && loginForm.username.$error.required">Required</span> 
 </div> 
 <div class="form-group" 
   ng-class="{'has-error': rc.loginForm.needsAttention(loginForm.password)}"> 
  <input class="form-control" name="password" type="password" 
    placeholder="Password" required ng-model="session.password" /> 
  <span class="help-block" 
    ng-show="rc.form.needsAttention(loginForm.password) && loginForm.password.$error.required">Required</span> 
 </div> 
 <div class="form-group"> 
  <button type="submit" class="btn btn-primary pull-right" 
    value="Login" title="Login"> 
   <span>Login</span> 
  </button> 
 </div> 
</form> 

样式如下

2016421174922051.png (469×328)

前端验证通过会调用login()。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn