Otentikasi
Cara paling umum dalam desain izin adalah kontrol akses berbasis peran RBAC. Gagasan dasarnya adalah bahwa berbagai izin untuk operasi sistem tidak secara langsung diberikan kepada pengguna tertentu, tetapi lebih untuk membuat pengumpulan peran antara set pengguna dan set izin. Setiap peran sesuai dengan set izin yang sesuai.
Setelah pengguna diberi peran yang sesuai, pengguna memiliki semua izin operasional untuk peran tersebut. Keuntungan dari ini adalah bahwa tidak perlu menetapkan izin setiap kali pengguna dibuat, cukup tetapkan peran pengguna yang sesuai, dan perubahan izin peran jauh lebih sedikit daripada perubahan izin pengguna, yang akan menyederhanakan manajemen izin pengguna dan mengurangi overhead sistem.
Dalam satu halaman aplikasi yang dibangun oleh Angular, kita perlu melakukan beberapa hal tambahan untuk mengimplementasikan arsitektur semacam itu. Dari perspektif proyek secara keseluruhan, ada sekitar 3 tempat yang perlu ditangani oleh insinyur front-end.
1. Pemrosesan UI (menilai apakah beberapa konten pada halaman ditampilkan berdasarkan izin yang dimiliki oleh pengguna)
2. Pemrosesan perutean (Ketika pengguna mengakses URL yang tidak memiliki izin untuk mengakses, ia melompat ke halaman dengan pesan kesalahan)
3. Pemrosesan Permintaan HTTP (Saat kami mengirim permintaan data, jika status yang dikembalikan adalah 401 atau 403, biasanya diarahkan ke halaman dengan pesan kesalahan)
Implementasi Kontrol Identitas Akses
Pertama, Anda perlu mendapatkan semua izin dari pengguna saat ini sebelum Angular dimulai, dan kemudian cara yang lebih elegan adalah dengan menyimpan hubungan pemetaan ini melalui layanan. Untuk apakah konten pada halaman ditampilkan sesuai dengan izin oleh UI. Setelah memproses ini, kita perlu menambahkan atribut "izin" tambahan untuk menambahkan rute saat menambahkan rute, dan menetapkan nilai untuk menunjukkan peran mana dengan izin yang dapat melompat ke URL ini, dan kemudian mendengarkan acara routechangestArt melalui Angular untuk memverifikasi apakah pengguna saat ini memiliki akses ke URL ini. Akhirnya, pencegat HTTP diperlukan untuk memantau ketika status dikembalikan oleh permintaan adalah 401 atau 403, melompat ke halaman ke halaman prompt kesalahan. Kira -kira ini adalah apa adanya, tampaknya agak terlalu banyak, tetapi sebenarnya sangat mudah untuk dihadapi.
Return 401, jalankan loginctrl, return 403, jalankan izinCtrl.
Dapatkan hubungan pemetaan izin sebelum berjalan sudut
Proyek Angular dimulai melalui NG-APP, tetapi dalam beberapa kasus kami berharap proyek Angular akan berada di bawah kendali kami. Misalnya, dalam hal ini, saya berharap dapat memperoleh semua hubungan pemetaan izin dari pengguna yang saat ini masuk dan kemudian memulai aplikasi sudut. Untungnya, Angular sendiri menyediakan metode ini, yaitu, Angular.Bootstrap ().
Daftar izin var; angular.element (dokumen) .ready (function () {$ .get ('/API/userPerMisi', function (data) {dimissionlist = data; Angular.Bootstrap (dokumen, ['app']);});});Mereka yang membaca dengan cermat mungkin memperhatikan bahwa penggunaan $ .get () digunakan di sini, dan tidak ada kesalahan menggunakan jQuery alih -alih Sumber $ Angular atau $ http, karena pada saat ini, Angular belum dimulai, dan kami tidak dapat menggunakan fungsinya.
Gunakan lebih lanjut kode di atas untuk menempatkan hubungan pemetaan yang diperoleh ke dalam layanan sebagai variabel global.
// app.js var app = angular.module ('myApp', []), daftar izin; app.run (function (izin) {izin.setpermissions (izinlist)}); angular.element (dokumen) .ready (function () {$ .get ('/API/userPerMisi', function (data) {dimissionlist = data; Angular.Bootstrap (dokumen, ['app']);});}); // common_service.js angular.module('myApp') .factory('permissions', function ($rootScope) { var permissionList; return { setPermissions: function(permissions) { permissionList = permissions; $rootScope.$broadcast('permissionsChanged') } }; });Setelah mendapatkan set izin dari pengguna saat ini, kami mengarsipkan set ini ke dalam layanan yang sesuai, dan kemudian melakukan 2 hal lagi:
(1) Simpan izin dalam variabel pabrik sehingga mereka selalu dalam memori, mewujudkan peran variabel global, tetapi tidak mencemari namespace.
(2) Acara siaran melalui $ siaran, ketika izin berubah.
1. Cara menentukan kekuatan komponen UI yang terlihat dan tersembunyi berdasarkan izin
Di sini kita perlu menulis arahan sendiri, yang akan menampilkan atau menyembunyikan elemen berdasarkan hubungan izin.
<!-Jika pengguna telah mengedit izin tautannya-> <div has-izis = 'Edit'> <a href = "/#/courses/{{id}}/edit"> {{name}} </a> </div>-jika pengguna tidak memiliki izin edit maka tampilkan teks saja itu (note the the " have-persmission = '! Edit'> {{name}} </div>Di sini saya melihat situasi ideal yang dapat Anda lewati dengan nama izin verifikasi properti yang memiliki izin, dan jika pengguna saat ini memilikinya, itu akan ditampilkan, dan jika tidak ada, itu akan disembunyikan.
angular.module ('myApp'). Directive ('haspermission', function (izin) {return {link: function (scope, elemen, attrs) {if (! _. isString (attrs.haspermission)) lempar "nilai haspermission harus berupa string"; var value = attrs.haspermission); if (notpermissionFlag) {value = value.slice (1) .trim (); togglevisabilityBasedOnPermission ();Perluas pabrik sebelumnya:
angular.module ('myApp'). Factory ('Izin', function ($ rootscope) {var izinlist; return {setPerMissions: function (izin) {izinlist = izin; $ rootscope. $ broadcast ('izinschanged')}, haspermission: function (function (function ('permission) {), haspermission: function (function) {evision) {evision) {evision. _.some (IzinList, Function (item) {if (_. ISSTRING (item.name)) Return item.name.trim () === Izin});2. Akses berbasis izin di rute
Gagasan bagian implementasi ini adalah sebagai berikut: Ketika kami mendefinisikan rute, kami menambahkan atribut izin, dan nilai atribut adalah izin yang harus kami akses URL saat ini. Kemudian, kami terus mendengarkan perubahan URL melalui acara RouteChangestArt. Setiap kali kita mengubah URL, periksa apakah URL yang akan dialihkan memenuhi persyaratan, dan kemudian memutuskan apakah itu akan dialihkan dengan sukses atau ke halaman prompt kesalahan.
app.config (function ($ routeProvider) {$ routeProvider .when ('/', {templateUrl: 'view/viewcourses.html', controller: 'viewCourSesctrl'}) .when ('/tidak sah', {Templateurl: 'view/views/hlhenh', controller ', {TemplateUrl:' view/views/hnt ', {TemplateRl:' views/hlren ('/tidak wajar', {TemplateUrl: 'views/hlren/horthhorized', {TemplateRl: 'view/{error,' views/hlren horeT ', {TemplateRl:' View/hlrens/hoThorized '. .shen ('/courses/: id/edit', {templateUrl: 'views/editcourses.html', controller: 'EditCourses', izin: 'Edit'});MainController.js atau IndexController.js (singkatnya, ini adalah pengontrol lapisan induk)
app.controller ('mainappctrl', fungsi ($ scope, $ location, izin) {$ scope. $ on ('$ routeChangestArt', function (lingkup, selanjutnya, saat ini) {var izin = selanjutnya. $$ route.Permission; jika (_. ISTRING (izin) && izin! });Haspermisi yang ditulis sebelumnya masih digunakan di sini, dan hal -hal ini sangat dapat digunakan kembali. Ini selesai. Sebelum setiap rute tampilan melompat, cukup menilai apakah ia memiliki izin untuk melompat ke pengontrol wadah induk.
3. Pemrosesan Permintaan HTTP
Ini harus relatif mudah ditangani, dan idenya sangat sederhana. Karena aplikasi sudut merekomendasikan alasan gaya RESTful, penggunaan protokol HTTP sangat jelas. Jika kode status yang dikembalikan oleh permintaan adalah 401 atau 403, itu berarti tidak ada izin, sehingga Anda bisa melompat ke halaman prompt kesalahan yang sesuai.
Tentu saja, kami tidak dapat memverifikasi secara manual dan meneruskan setiap permintaan sekali, jadi kami pasti harus membutuhkan filter total. Kodenya adalah sebagai berikut:
angular.module ('myApp') .config (function ($ httpprovider) {$ httpprovider.responseinterceptor.push ('SecurityInterceptor');}) .provider ('functionceptor', function () {this. $ get = function ($ location, $ {function) {function (function () {this. $ get = function ($ location, $ function, function {function) {function. if response.status === 403 || response.status === 401) {$ location.path ('/tidak sah');Dengan menulis ini, Anda hampir dapat menyadari manajemen izin dan kontrol bagian front-end dalam mode pemisahan front-end ini.
Verifikasi bentuk
Petunjuk Verifikasi Front-End AngularJS
var rcsubmitDirective = {'rcsubmit': function ($ parse) {return {restrict: "a", membutuhkan: ["rcsubmit", "? 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. $ tidak valid && (fieldmodelcontroller. $ kotor || this.attempted); } else {return FormController && FormController. $ Invalid && (FormController. $ Dirty || this.attempted); }}; }, compile: function () {return {pre: function (scope, formElement, atribut, controllers) {var submitController = controllers [0]; var formcontroller = controllers.length> 1? pengontrol [1]: null; SubmitController.SetFormController (FormController); scope.rc = scope.rc || {}; scope.rc [attributes.name] = SubmitController; }, POST: FUNGSI (SCOPE, FormElement, Atribut, Controllers) {Var SubmitController = Controllers [0]; var formcontroller = controllers.length> 1? pengontrol [1]: null; var fn = $ parse (attributes.rcsubmit); formelement.bind ("Kirim", fungsi (event) {submitController.setAttempted (); if (! SCOPE. $$ fase) lingkup. $ apply (); if (! FormController. $ valid) return; scope. $ apply (function () {fn (scope, {$ event: event});}); }}; }}; }}; }}; }}; }}; }}; }}; }};Verifikasi berlalu
<form name="loginForm" novalidate ng-app="LoginApp" ng-controller="LoginController" rc-submit="login()"> <div ng-class="{'has-error': rc.loginForm.needsAttention(loginForm.username)}"> <input name="username" type="text" placeholder = "nama pengguna" diperlukan ng-model = "session.userName"/> <span ng-show = "rc.form.needsattention (loginform.username) && loginform.username. $ error.required"> Diperlukan </span> </div> <Div ng-class = "{'has-error': has-error ': has-error': has-error ': has-error': has-error ': rc.loginform.needsattention (loginForm.password)} "> <input name =" kata sandi "type =" kata sandi "placeholder =" kata sandi "diperlukan ng-model =" session.password "/<span ng-show =" rc.form.needsattention (loginform. <div> <tombol type = "kirim" value = "Login"> <span> Login </span> </button> </div> </form>Gayanya sebagai berikut
Login () akan dipanggil setelah verifikasi front-end berlalu.