Bucaq - Rol və şəxs statusuna əsasən icazəni necə yoxlamaq olar

Hal-hazırda, tətbiqinizin təsdiqləmə və təsdiqləmə prosesində olması çox yaygındır. İnternetdən icazə kitabxanaları və texnikalarını axtarırsınızsa, yalnız rol əsaslı avtorizasiya təklif edən, ancaq səhifəyə girişi əngəlləyən həll yollarını asanlıqla tapa bilərsiniz.

TL üçün; DR burada demo və istifadə olunan koddur.

Şəkil kreditləri

Cismin dövlət icazəsi nədir?

Düşünürəm ki, bu yazını yazanda adımdan daha yaxşı bir şey yoxdu. Ancaq daha çox və ya daha az söylədiyim şey, mövcud istifadəçi statusu X statusundan və digərindən asılı olduqda, mövcud istifadəçini müəyyən bir tədbir görmək qabiliyyətindən məhrum etməli olduğunuz vəziyyətlərlə əlaqədardır. Müəssisə aktiv olduqda qabiliyyət Y vəziyyətini təyin edir və ən pis hal bütün bunlar eyni ekranda və ya eyni komponentdə olanda baş verdi. Rol bazası icazəsi olan bütün kitabxanalar bu problemi xilas edir. Rol əsaslı səhifələrin həll yollarının qarşısını aldığı müxtəlif məqalələri oxumaqdan bezdim və heç nəyi nəzərə almadan düşünməyə və proqramlaşdırmağa başladım. Birdən dörd hissədən ibarət olan bu tip problemə sadə, çətin olmayan və çox çevik bir həll tapdım.

  • Cari istifadəçi məlumatını təmin etmək üçün bir xidmət (həqiqətən vacib olan cari istifadəçinin mənsub olduğu və ya tətbiqdə onlara təyin edilmiş istifadəçi rollarını müəyyənləşdirməyin bir yolu).
  • Bir iş axınına icazə kartı (JSON faylı)
  • İcazə yoxlamasını həyata keçirən bir avtorizasiya xidməti
  • Avtorizasiya xidmətini yoxlamaq üçün bir təlimat

Addım 1: Cari istifadəçi rollarını alın

Daha sonra istifadəyə üstünlük verdiyiniz kimi server tərəfdən (ilk dəfə) və ya bir seansdan və ya cookies-dən əldə etmək üçün bir xidmət həyata keçirin. İstifadəçi bacarıqlarının (rollarının) siyahısını təmin etmək vacibdir.

// Misal {Ad: "John Doe", e-poçt: '[email protected]', rollar: ['satıcı', 'satıcı_manager'], <- bu girişToken'dən asılıdır: 'Alotofleters, dieanaccesstokenhahahaaa!' ... daha çox şey
}

Mənim vəziyyətimdə bu daha çox və ya daha az görünür:

// buraya idxal ...
@Injectable () ixrac sinif CurrentUserService {şəxsi userSubject = yeni ReplaySubject (1); Şəxsi hasUser = saxta; Konstruktor (şəxsi istifadəçilərApi: UserApi) {} public getUser (): Müşahidə edilə bilən {if (! this.hasUser) {this.fetchUser (); } this.userSubject.asObservable () qayıt } public fetchUser (): boşluq {this.usersApi.getCurrent () // userInfo əldə etmək üçün http <. = abunə .subscribe (user => {// user bu rolları vermiş olmalıdır.hasUser = true; bu. userSubject.next (istifadəçi); this.userSubject.complete ();}, (səhv) => {this.hasUser = saxta; this.userSubject.error (səhv);}); }}

İkinci addım: iş axınını və avtorizasiya baxışını yaradın

Bu fərqli qurumlar və öz dövlətləri ilə bir ağac quraraq nə edə biləcəyimizi və kimin edə biləcəyimizi göstərməkdən başqa bir şey deyil. Məsələn, aşağıdakı satış prosesini nəzərdən keçirək: Tətbiqimizin bir çox rol növləri ola bilər. Nümunəmizdə rolları SATIŞ, ARXITECT həlləri və MÜŞTƏRİ üçün təyin edirik.

Proses haqqında danışmamağımız üçün:

  • Birincisi, Satıcı, fürsət statusu yaratma ehtimalı olan Yeni Fürsət əlavə etmə aksiyasını həyata keçirməklə bir fürsət tapır
  • Bu zaman MÜŞTƏRİ VƏ Satıcı fürsətə tələbləri əlavə edə bilər ki, hər ikisi də tələblər edildikdə Əlavə tələbləri əlavə etmə hərəkətindən istifadə edə bilsinlər. Fürsət statusu Təqdim edilə bilər
  • Tələblər yerinə yetirildikdən sonra, ARCHITECT bir həll tələb etmək üçün bir həll əlavə etmək istəyə bilər: həll yükləyin və status həll oluna bilər
  • Çözüm yerləşdirildikdən sonra MÜŞTƏRİ qəbul etməyi istəyə bilər ki, həllini təsdiqləmək üçün bir hərəkət tələb olunsun və status həll_ təsdiqləndi

Buradakı prosesi qısaldacağıq, əks halda bu çox artacaq və bu oxunuşda belə deyil. Bu prosesə, xəritəçəkməyə və fürsət müəssisəsinin bir status izləmə sahəsinə sahib olmasına əsaslanaraq iş prosesimiz bu kimi görünür:

{"Fürsət": {"addOpportunity": {"icazə verilən rollar": ["SELLER"]}}, "yaradıldı": {"addRequidence": {"icazəRoles": ["Satıcı", "MÜŞTƏRİ"]}}, " təqdim ": {" addSolution ": {" icazəRoles ": [" ARCHITECT "]}}," həll edildi ": {" təsdiqSolution ": {" icazəRoles ": [" CLIENT "]}}}}

Addım 3: İş axını və avtorizasiya baxışını istifadə etmək üçün təsdiqləmə avtorizasiya xidməti

Prosesi bir iş axını və icazə xəritəsinə uyğunlaşdırdıqdan sonra istifadə etmək üçün bir xidmət yaratmalı və istifadəçinin səlahiyyətli olub olmadığını yoxlamalıyıq. Bu belə görünə bilər:

// Buraya idxal təlimatları // Yeri gəlmişkən, Angular-Cli-də JSON faylını // Environment.ts-ə qoya bilərik
@ Injectable () ixrac sinif WorkflowEvents {yalnız oxumaq üçün özəl WORKFLOW_EVENTS = Ətraf mühit ['İş axını']; şəxsi istifadəçi rolları: dəsti ;
// 1-ci addımı xatırlayırsınız? burada konstruktor istifadə olunur (Şəxsi currentUserService: CurrentUserService) {} // Boolean müşahidə olunan ictimai yoxlamanı qaytarırAvtorasiya (yol: hər hansı): Müşahidə edilə bilər {// Rolları yalnız bir dəfə yükləyirik (! This.userRoles) {bu.currentUserService.getUser () .map (currentUser => currentUser.roles) .do (role => {const role = role.map ( rol => role.name); this.userRoles = yeni Dəst (rollar);}) .map (rol => this.doCheckAuthorization (path)); } Observable.of (this.doCheckAuthorization (yol)) qayıt; } xüsusi doCheckAuthorization (yol: string []): boolean {if (path.length) {const giriş = this.findEntry (bu.WORKFLOW_EVENTS, yol); if (giriş && giriş ['allowRoles'] && this.userRoles.size) {return entry.permissionsRoles .some (icazəRole => this.userRoles.has (icazəRole)); } yalan qaytarma; } yalan qaytarma; }
/ ** * Keçid xətləri əsasında iş axını xəritəsi girişlərini rekursiv olaraq axtarın * / xüsusi findEntry (currentObject: any, key: string [], index = 0) {const key = düymələr [index]; əgər (currentObject [key] && index

Əsasən, etibarlı bir giriş axtarmalı və mövcud istifadəçi rollarının icazə verilən Rollara daxil olub olmadığını yoxlamalısınız.

Fayl 4: Siyasət

Cari istifadəçi rolları, bir iş axınına icazə vermə ağacı və cari istifadəçi rolları üçün icazəni yoxlamaq üçün bir xidmətə sahib olduqdan sonra bunu direktiv vasitəsi ilə 2/4 bucaq altında həyata keçirməliyik. Əvvəlcə yazdığım direktiv, ekran CSS atributunu dəyişdirən bir atribut direktivi idi. Ancaq bu, performans problemlərinə səbəb ola bilər, çünki DOM-da saxlanan komponentlər hələ də yüklənir. Buna görə istifadə edilməmiş elementlərin yüklənməməsi üçün hədəf elementin və onun nəslinin DOM-nu dəyişdirə biləcəyimiz üçün struktur göstərişlərdən (bu həmkarım Petyo Cholakov-a təşəkkür edirəm (buradakı fərqi gör) yaxşıdır.

@Directive ({Seçici: '[appCanAccess]'}) ixrac sinfi CanAccessDirective OnInit, OnDestroy {@ Input ('appCanAccess') appCanAccess: string | simli []; xüsusi icazə $: abunə; Konstruktor (şəxsi şablonRef: TemplateRef , şəxsi görünüşContainer: ViewContainerRef, özəl iş axınıEvents: WorkflowEvents) {} ngOnInit (): boşluq {this.applyPermission (); } şəxsi tətbiqPermission (): boş {{ .viewContainer.clear ();}}); } ngOnDestroy (): boşluq {this.permission $ .unsubscribe (); }}

Sonda ortaya çıxan iş

İndi ehtiyac duyduğumuz şeyin hamısını tətbiq etmək üçün vaxtdır. HTML şablonumuzda etməli olduğumuz yeganə şey aşağıdakı koddur

Deyək ki, imkan obyekti olan bir nümunə komponentimiz var:

@ Komponent ({selector: 'sp-pricing-panel', şablon: ` 
 
 
 
 `}) İxrac sinif SampleComponent OnInit tətbiq edir {@ Input () OpportunityObject: any;
Dizayner () {} ngOnInit () {}}

Və bu, istifadəçi rollarına və şəxs statusuna əsaslanan davranışı təmsil edən sadə bir komponentə sahib ola bilərik.

Həmkarlarım Petyo və Govind-ə görə pis kodlaşdırmağıma görə və tənqid etdiyim üçün ehtiyaclarımıza mükəmməl cavab verən bu həll yolu tapa bildik. Ümid edirəm ki, bu da sizə kömək edir.

IYUN 2018, kiçik iş nümunəsi => https://emsedano.github.io/ng-entity-state/