कोणीय - भूमिका और इकाई-राज्यों के आधार पर प्राधिकरण की जांच कैसे करें

आजकल आपको अपने आवेदन में प्रमाणीकरण और प्राधिकरण के निर्माण की स्थिति में खोजने के लिए बहुत आम है, प्राधिकरण पुस्तकालयों और तकनीकों के लिए वेब पर खुदाई करना हमेशा समाधान खोजना आसान होता है जो केवल भूमिका-आधार प्राधिकरण प्रदान करता है जो केवल एक पृष्ठ तक पहुंचने से रोकता है, हालांकि लगभग अक्सर ऐसा होता है कि आपको कुछ और चाहिए, इकाई-राज्य प्राधिकरण।

TL के लिए; DR यहां डेमो है और डेमो में इस्तेमाल किया गया कोड है।

चित्र साभार

इकाई-राज्य प्राधिकरण क्या बिल्ली है?

खैर, मुझे लगता है कि इस पोस्ट को लिखते समय मेरे नाम में कुछ भी बेहतर नहीं था। हालाँकि कमोबेश मैं जो कहने की कोशिश कर रहा हूं, वह उन स्थितियों से संबंधित है, जब आपको वर्तमान उपयोगकर्ता को विशिष्ट कार्रवाई लागू करने की क्षमता प्रदान करने या अन-अनुदान देने की आवश्यकता होती है, यदि वर्तमान इकाई स्थिति एक्स राज्य पर निर्भर करती है और एक अलग क्षमता जब इकाई होती है राज्य वाई राज्य पर निर्भर करता है और यह सबसे खराब तब आया जब यह सब एक ही स्क्रीन पर या एक ही घटक में होना चाहिए। भूमिका-आधार प्राधिकरण वाला कोई भी पुस्तकालय आपको इस समस्या से बचाएगा।
रोल-बेस पेज के साथ अलग-अलग लेखों को पढ़ने से थकने वाले समाधानों को रोकते हुए, मैंने अभी तक बिना कुछ सोचे-समझे और कोडिंग शुरू कर दी थी, और अचानक यह वहाँ हो गया, मुझे इस तरह की समस्याओं को हल करने के लिए सरल, सीधा और बहुत लचीला समाधान मिला और इसकी रचना चार से हुई अवयव।

  • वर्तमान उपयोगकर्ता जानकारी प्रदान करने के लिए एक सेवा (जो वास्तव में मामला उपयोगकर्ता की भूमिकाएं प्रदान करने का एक तरीका है जो वर्तमान उपयोगकर्ता के पास है या आवेदन में खेलने के लिए दी गई है)
  • एक वर्कफ़्लो-अनुमतियाँ मैप (JSON फ़ाइल)
  • वास्तव में प्राधिकरण जांच करने के लिए एक अनुमति सेवा
  • जाँच सेवा का उपभोग करने का एक निर्देश

चरण 1: वर्तमान उपयोगकर्ता भूमिकाएं प्राप्त करें

सर्वर साइड (पहली बार) या सत्र या कुकीज़ से प्राप्त करने के लिए एक सेवा को लागू करें क्योंकि आप इसके बाद के उपयोगों के लिए पसंद करते हैं, यहां महत्वपूर्ण बात यह है कि उपयोगकर्ता को क्षमताओं की भूमिका (सूची) प्रदान करना है।

// उदाहरण
{
  नाम: 'जॉन डो',
  ईमेल: '[email protected]',
  भूमिकाएँ: ['विक्रेता', 'विक्रेता_ प्रबंधक'], <- यही मायने रखता है
  accessToken: 'alotofletersrepretinganaccesstokenhahaaaaa!'
  ... अधिक सामान
}

मेरे मामले में कमोबेश यही है कि यह कैसा दिखता है:

// यहाँ आयात ...
@Injectable ()
निर्यात वर्ग CurrentUserService {
  निजी उपयोगकर्तासुबेज = नया रिप्लेसेबजेक्ट <उपयोगकर्ता> (1);
  निजी hasUser = false;

  कंस्ट्रक्टर (निजी उपयोगकर्ताअपी: यूजरअपी) {
  }

  सार्वजनिक getUser (): अवलोकनीय <उपयोगकर्ता> {
    अगर (यह। हैसर) {
      this.fetchUser ();
    }
    इसे वापस लौटाएं ।userSubject.asObservable ();
  }

  सार्वजनिक रूप से लाने वाला (): शून्य {
      this.usersApi.getCurrent () // <== http कॉल userInfo लाने के लिए
        । सदस्यता लें (उपयोगकर्ता => {
          // उपयोगकर्ता को भूमिकाएं दी जानी चाहिए
          this.hasUser = true;
          this.userSubject.next (उपयोगकर्ता);
          this.userSubject.complete ();
        }, (त्रुटि) => {
          this.hasUser = false;
          this.userSubject.error (त्रुटि);
        });
  }

}

दूसरा चरण: अपने वर्कफ़्लो और अनुमतियाँ मैप बनाएँ

यह कुछ भी नहीं है, लेकिन हम अलग-अलग संस्थाओं और अपने स्वयं के राज्यों के साथ एक पेड़ का निर्माण कर सकते हैं और हम क्या कर सकते हैं। उदाहरण के लिए, चलो निम्नलिखित बिक्री प्रक्रिया की कल्पना करते हैं; हमारे आवेदन में कई प्रकार की भूमिका हो सकती है। हमारे उदाहरण के लिए SELLER, समाधान ARCHITECT और CLIENT में भूमिकाओं का नक्शा दें।

प्रक्रिया के बारे में बात करें:

  • पहले विक्रेता कार्रवाई को निष्पादित करके एक बिक्री का अवसर देता है, इसलिए नया अवसर जोड़ें ताकि अवसर राज्य संभवतः बना हो
  • इस बिंदु पर, ग्राहक और विक्रेता आवश्यकताओं को अवसर में जोड़ सकते हैं, इसलिए दोनों कार्रवाई लागू कर सकते हैं आवश्यकताओं को रखा जाता है जब आवश्यकताओं को रखा जाता है तो अवसर की स्थिति प्रस्तुत की जा सकती है।
  • एक बार जब आवश्यकताओं को रखा जाता है तो ARCHITECT एक समाधान जोड़ना चाहता है, तो उसे एक कार्रवाई की आवश्यकता होती है: समाधान अपलोड करें और शायद राज्य हल करने के लिए बदल सकता है।
  • एक बार समाधान प्रदान करने के बाद, CLIENT स्वीकार करना चाह सकता है इसलिए उसे समाधान को मंजूरी देने के लिए एक कार्रवाई की आवश्यकता होती है और राज्य solution_approved में बदल जाएगा

हम यहां प्रक्रिया में कटौती करने जा रहे हैं अन्यथा यह बहुत बढ़ जाएगा और इस पढ़ने के लिए ऐसा नहीं है। तो इस प्रक्रिया के आधार पर मैपिंग और यह मानते हुए कि अवसर निकाय में एक क्षेत्र है जो राज्य को ट्रैक करता है, हमारे वर्कफ़्लो इस तरह दिखाई देंगे:

{
  "अवसर": {
    "addOportunity": {"allowRoles": ["विक्रेता"]}},
    "बनाया था": {
      "addRequirement": {"allowRoles": ["विक्रेता", "ग्राहक"]}
    },
    "प्रस्तुत": {
      "addSolution": {"allowRoles": ["ARCHITECT"]}
    },
    "हल किया": {
      "अनुमोदन": {"अनुमत्य": ["ग्राहक"]}
    }
}

चरण 3: वर्फ़्लो और अनुमतियों के नक्शे का उपभोग करने के लिए जाँच प्राधिकरण सेवा

अब जब हमारे पास वर्कफ़्लो और अनुमतियों के नक्शे में मैप की गई प्रक्रिया है, तो हमें इसका उपभोग करने के लिए एक सेवा बनाने की आवश्यकता है और यह जाँचने के लिए कि उपयोगकर्ता अधिकृत है या नहीं और यह इस तरह दिख सकता है:

// आयात विवरण यहाँ
// कोणीय-सीएलआई में जिस तरह से हम JSON फाइल डाल सकते हैं
// enviroment.ts
@Injectable ()
निर्यात वर्ग WorkflowEvents {
  निजी आसानी से WORKFLOW_EVENTS = पर्यावरण ['वर्कफ़्लो'];
  निजी उपयोगकर्ता: सेट करें ;
  // क्या आपका चरण 1 याद है? इसका उपयोग यहाँ किया जाता है
  कंस्ट्रक्टर (निजी currentUserService: CurrentUserService) {
  }
  // एक बूलियन अवलोकन योग्य है
  सार्वजनिक जाँचअभिव्यक्ति (पथ: कोई भी): अवलोकन योग्य  {
    // हम केवल एक बार भूमिकाओं को लोड कर रहे हैं
   यदि (यह .useroles) {
      यह लौटाएँ। समवर्तीUserService.getUser ()
        .map (currentUser => currentUser.roles)
        .do (भूमिकाएँ =>)
          const भूमिकाओं = भूमिकाएँ ।map (भूमिका => भूमिका.नाम);
          this.userRoles = नया सेट (भूमिका);
        })
        .map (भूमिकाएँ => this.doCheckAuthorization (पथ));
    }
    ओब्जर्वेबल पर लौटें ।of (this.doCheckAuthorization (पथ));
  }

  निजी doCheckAuthorization (पथ: स्ट्रिंग []): बूलियन {
    अगर (पाथ.लिफ्टिंग) {
      const प्रविष्टि = this.findEntry (यह .ORKFLOW_EVENTS, पथ);
      अगर (प्रविष्टि और प्रविष्टि) ['अनुमत अनुमतियाँ']
             && this.userRoles.size) {
        वापसी प्रविष्टि
        .some (allowRole => this.userRoles.has (allowRole));
      }
      विवरण झूठा है;
    }
    विवरण झूठा है;
  }
/ **
 * पथ स्ट्रिंग्स के आधार पर वर्कफ़्लो-मैप प्रविष्टि की पुन: खोज करें
 * /
निजी findEntry (currentObject: any, कुंजियाँ: string [], index = 0) {
    const key = keys [सूचकांक];
    अगर (currentObject [कुंजी] && इंडेक्स 

मूल रूप से मान्य प्रविष्टि देखने और यह जांचने के लिए कि क्या करता है कि क्या वर्तमान उपयोगकर्ता भूमिका अनुमतियों में शामिल हैं।

फ़ाइल 4: निर्देश

एक बार जब हमारे पास वर्तमान उपयोगकर्ता भूमिकाएं होती हैं, तो एक वर्कफ़्लो अनुमतियाँ ट्री, और वर्तमान उपयोगकर्ता भूमिकाओं के लिए प्राधिकरण की जांच करने के लिए एक सेवा, अब हमें इसे जीवित रखने का एक तरीका चाहिए, और कोणीय 2/4 में सबसे अच्छा तरीका एक निर्देश है। प्रारंभ में मैंने जो निर्देश लिखा था वह एक विशेषता निर्देश था जो प्रदर्शन सीएसएस विशेषता को टॉगल कर रहा था, लेकिन यह प्रदर्शन के मुद्दों को जन्म दे सकता था क्योंकि अभी भी डीओएम को लोड हो रहा है, इसलिए संरचनात्मक निर्देशों का उपयोग करना बेहतर है (इस अच्छे कैच के लिए मेरे सहयोगी पेटियो चेकोकोव का धन्यवाद) यहाँ अंतर देखें) क्योंकि हम टार्गेट एलिमेंट के DOM को मॉडिफाई कर सकते हैं और यह डिडेंट है इसलिए हम यूज्ड एलिमेंट्स की लोडिंग से बच सकते हैं।

@Directive ({
  चयनकर्ता: '[appCanAccess]'
})
निर्यात वर्ग CanAccessDirective लागू करता है, OnDestroy {
  @Input ('appCanAccess') appCanAccess: स्ट्रिंग | स्ट्रिंग [];
  निजी अनुमति $: सदस्यता;

  कंस्ट्रक्टर (निजी टेम्प्लेट रीफ: टेम्प्लेट रीफ <कोई>,
              निजी व्यू कॉर्नर: ViewContainerRef,
              निजी वर्कफ़्लो: वर्कफ़्लोइवेंट्स) {
  }

  ngOnInit (): शून्य {
    this.applyPermission ();
  }

  निजी आवेदन (): शून्य {
    this.permission $ = this.workflowEvents
                        .checkAuthorization (this.appCanAccess)
      । सदस्यता लें (अधिकृत => {
        अगर (अधिकृत) {
          this.viewContainer.createEmbeddedView (this.templateRef);
        } अन्य {
          this.viewContainer.clear ();
        }
      });
  }

  ngOnDestroy (): शून्य {
    this.permission $ .unsubscribe ();
  }

}

अंत में परिणामी काम

अब हमारे पास जो कुछ भी है, हमें उन्हें कार्रवाई में लगाने का समय है। इसलिए हमारे HTML टेम्पलेट में, केवल एक चीज जो हमें करने की आवश्यकता है, वह निम्न कोड जैसा कुछ है

मान लें कि हमारे पास एक नमूना घटक है जिसमें अवसर वस्तु शामिल है:

@Component ({
  चयनकर्ता: 'मूल्य-निर्धारण-पैनल',
  टेम्पलेट: `
<एक ही नमूना घटक>
    <बटन * appCanAccess = "['अवसर', 'addOkutunity']">
      अवसर जोड़ें
    
<ऐड-आवश्यकता-घटक * appCanAccess = "['अवसर', chanceObject.state, 'addRequirement']"> 
<ऐड-सॉल्यूशन-घटक * appCanAccess = "['अवसर', chanceObject.state, 'addSolution']"> 
<स्वीकृत-समाधान-घटक * appCanAccess = "['अवसर', chanceObject.state, 'approveSolution']"> 
 `
})
निर्यात वर्ग

  @Input () अवसर: कोई भी;
  कंस्ट्रक्टर () {
  }

  ngOnInit () {
  }
}

और यह है, हम उपयोगकर्ता भूमिकाओं और इकाई राज्य के आधार पर एक सरल घटक प्रस्तुत व्यवहार कर सकते हैं।

मेरे सहयोगियों पेटियो और गोविंद के लिए धन्यवाद और आलोचकों को मेरी खराब कोडिंग के लिए हम इस समाधान को पा सकते हैं जो हमारी आवश्यकताओं के लिए पूरी तरह से काम कर सकता है, मुझे आशा है कि यह आपकी भी मदद करता है।

जून 2018, छोटा नमूना काम कर रहा है => https://emsedano.github.io/ng-entity-state/

यह सभी देखें

Android डेवलपर होने के लिए मुझे जावा को कितना अच्छा जानना चाहिए? कैसे एक संगीत कार्यक्रम के लिए तैयार करने के लिएमेरी वेबसाइट में बहुत सारे पृष्ठ हैं और कुछ पुराने पृष्ठ नेविगेशन में 50 वें पृष्ठ पर चले गए हैं। मैं ऐसे पृष्ठों की पहुँच क्षमता में सुधार कैसे करूँ, क्योंकि सभी पृष्ठ होम पेज से नहीं जोड़े जा सकते हैं?मैं यूआई / यूएक्स डिजाइनर के रूप में फ्रीलांस काम कैसे कर सकता हूं? किसी को पहली बार असली वेबसाइट डिजाइन करने में कितना समय लगता है? मेरे पास एक ऐप / वेबसाइट के लिए एक विचार है; हालाँकि, मुझे नहीं पता कि इस प्रक्रिया को कैसे आगे बढ़ाया जाए। एक सामान्य विचार होने के बाद मुझे क्या करना चाहिए?वर्डप्रेस डेवलप की गई वेबसाइट के लिए आप एक बेहतरीन एसईओ कैसे सुनिश्चित करते हैं? कैसे इंस्टाग्राम संदेशों को बचाने के लिए