एसीएल और नियंत्रकों
सबसे पहले: ये अलग-अलग चीजें / परतें होती हैं। जैसा कि आप अनुकरणीय नियंत्रक कोड की आलोचना करते हैं, यह दोनों को एक साथ रखता है - सबसे स्पष्ट रूप से बहुत तंग।
tereško पहले से ही एक तरह से उल्लिखित है कि आप डेकोरेटर पैटर्न के साथ इसे और अधिक कैसे कम कर सकते हैं।
मैं उस मूल समस्या को देखने के लिए सबसे पहले एक कदम पीछे जाऊंगा, जिस पर आप चर्चा कर सकते हैं।
एक तरफ आप नियंत्रकों को चाहते हैं कि वे जो काम करने की आज्ञा दें (कमांड या एक्शन, उसे कमांड कहते हैं)।
दूसरी ओर आप अपने आवेदन में एसीएल लगाने में सक्षम होना चाहते हैं। इन ACL के कार्य का क्षेत्र होना चाहिए - यदि मैंने आपके प्रश्न को सही समझा है - आपके अनुप्रयोगों के कुछ आदेशों तक पहुँच को नियंत्रित करने के लिए।
इसलिए इस तरह के अभिगम नियंत्रण को कुछ और चाहिए जो इन दोनों को एक साथ लाए। उस संदर्भ के आधार पर जिसमें एक कमांड को निष्पादित किया जाता है, ACL को किक करता है और निर्णय लेने की आवश्यकता होती है कि क्या किसी विशिष्ट विषय (जैसे उपयोगकर्ता) द्वारा एक विशिष्ट कमांड निष्पादित किया जा सकता है या नहीं।
आइए इस बिंदु को संक्षेप में बताएं कि हमारे पास क्या है:
ACL घटक यहां केंद्रीय है: इसे कमांड के बारे में कम से कम कुछ जानने की जरूरत है (कमांड को सटीक रूप से पहचानने के लिए) और इसे उपयोगकर्ता की पहचान करने में सक्षम होना चाहिए। उपयोगकर्ताओं को आम तौर पर एक विशिष्ट आईडी द्वारा आसानी से पहचाना जाता है। लेकिन अक्सर वेबएप्लिकेशंस में ऐसे उपयोगकर्ता होते हैं जिनकी पहचान बिल्कुल नहीं होती है, जिन्हें अक्सर अतिथि, अनाम, हर कोई आदि कहा जाता है। इस उदाहरण के लिए हम मानते हैं कि ACL उपयोगकर्ता ऑब्जेक्ट का उपभोग कर सकता है और इन विवरणों को दूर कर सकता है। उपयोगकर्ता ऑब्जेक्ट अनुप्रयोग अनुरोध ऑब्जेक्ट के लिए बाध्य है और ACL इसका उपभोग कर सकता है।
एक कमांड की पहचान करने के बारे में क्या? एमवीसी पैटर्न की आपकी व्याख्या बताती है कि एक कमांड एक क्लासनाम और एक विधि नाम का यौगिक है। यदि हम अधिक बारीकी से देखते हैं तो कमांड के लिए तर्क (पैरामीटर) भी हैं। तो यह पूछने के लिए वैध है कि वास्तव में एक कमांड की पहचान क्या है? Classname, methodname, संख्याओं या तर्कों के नाम, यहां तक कि किसी भी तर्कों के अंदर डेटा या इस सब का मिश्रण?
आपके ACL'ing में कमांड को पहचानने के लिए आपको किस स्तर के विवरण पर निर्भर करता है, यह बहुत भिन्न हो सकता है। उदाहरण के लिए, आइए इसे सरल रूप से रखें और निर्दिष्ट करें कि एक कमांड को क्लासनाम और विधि के नाम से पहचाना जाता है।
तो ये तीन भाग (ACL, Command और User) एक दूसरे से कैसे जुड़े हैं इसका संदर्भ अब अधिक स्पष्ट है।
हम कह सकते हैं, एक काल्पनिक एसीएल के साथ हम पहले से ही निम्नलिखित कर सकते हैं:
$acl->commandAllowedForUser($command, $user);
यहां देखें कि क्या होता है: कमांड और यूजर दोनों को पहचानने योग्य बनाकर, एसीएल यह काम कर सकता है। ACL का कार्य उपयोगकर्ता वस्तु और ठोस कमांड दोनों के काम से असंबंधित है।
केवल एक हिस्सा गायब है, यह हवा में नहीं रह सकता है। और यह नहीं है। इसलिए आपको उस स्थान का पता लगाने की आवश्यकता है जहां पहुंच नियंत्रण को किक करने की आवश्यकता है। आइए एक नज़र डालते हैं कि मानक वेबपेपलेशन में क्या होता है:
User -> Browser -> Request (HTTP)
-> Request (Command) -> Action (Command) -> Response (Command)
-> Response(HTTP) -> Browser -> User
उस स्थान का पता लगाने के लिए, हमें पता है कि कंक्रीट कमांड निष्पादित होने से पहले यह होना चाहिए, इसलिए हम उस सूची को कम कर सकते हैं और केवल निम्नलिखित (संभावित) स्थानों पर ध्यान देने की आवश्यकता है:
User -> Browser -> Request (HTTP)
-> Request (Command)
अपने आवेदन में कुछ बिंदु पर आप जानते हैं कि एक विशिष्ट उपयोगकर्ता ने एक ठोस कमांड करने का अनुरोध किया है। आप पहले से ही यहाँ कुछ प्रकार का कार्य कर रहे हैं: यदि कोई उपयोगकर्ता एक कमांड का अनुरोध करता है जो मौजूद नहीं है, तो आप उस कमांड को निष्पादित करने की अनुमति नहीं देते हैं। तो जहां-जहां आपके आवेदन में होता है वहां "वास्तविक" एसीएल चेक जोड़ने के लिए एक अच्छी जगह हो सकती है:
कमांड स्थित हो गया है और हम इसकी पहचान बना सकते हैं ताकि एसीएल इससे निपट सके। यदि उपयोगकर्ता के लिए कमांड की अनुमति नहीं है, तो कमांड को निष्पादित नहीं किया जाएगा (कार्रवाई)। हो सकता है कि मामले के लिए अनुरोध के CommandNotAllowedResponse
बजाय CommandNotFoundResponse
एक ठोस आदेश पर हल नहीं किया जा सकता है।
वह स्थान जहाँ एक ठोस HTTPRequest की मैपिंग को कमांड पर मैप किया जाता है, अक्सर रूटिंग कहा जाता है । चूंकि रूटिंग में पहले से ही कमांड का पता लगाने का काम होता है, इसलिए यह जांचने के लिए इसे विस्तारित क्यों नहीं किया जाता है कि क्या कमांड को वास्तव में प्रति एसीएल की अनुमति है? उदाहरण के Router
लिए एक एसीएल जागरूक राउटर का विस्तार करके RouterACL
:। यदि आपका राउटर अभी तक नहीं जानता है User
, तो यह Router
सही जगह नहीं है, क्योंकि ACL'ing के लिए केवल कमांड ही नहीं, बल्कि उपयोगकर्ता को भी पहचानना होगा। तो यह स्थान अलग-अलग हो सकता है, लेकिन मुझे यकीन है कि आप आसानी से उस स्थान का पता लगा सकते हैं, जिसे आपको बढ़ाने की आवश्यकता है, क्योंकि यह वह स्थान है जो उपयोगकर्ता और कमांड की आवश्यकता को पूरा करता है:
User -> Browser -> Request (HTTP)
-> Request (Command)
उपयोगकर्ता शुरुआत के बाद से उपलब्ध है, कमान पहले के साथ Request(Command)
।
इसलिए प्रत्येक कमांड के ठोस कार्यान्वयन के अंदर अपनी एसीएल जांचों को डालने के बजाय , आप इसे पहले रखें। आपको किसी भी भारी पैटर्न, जादू या किसी भी चीज की आवश्यकता नहीं है, एसीएल यह काम करता है, उपयोगकर्ता यह काम करता है और विशेष रूप से कमांड यह काम करता है: बस कमांड, और कुछ नहीं। कमांड को यह जानने में कोई दिलचस्पी नहीं है कि क्या भूमिकाएं उस पर लागू होती हैं या नहीं, अगर यह कहीं संरक्षित है या नहीं।
तो बस चीजों को अलग रखें जो एक दूसरे से संबंधित नहीं हैं। सिंगल रिस्पॉन्सिबिलिटी प्रिंसिपल (एसआरपी) के थोड़ा रीवॉर्डिंग का उपयोग करें : कमांड को बदलने का केवल एक कारण होना चाहिए - क्योंकि कमांड बदल गया है। इसलिए नहीं कि अब आप अपने आवेदन में ACL'ing का परिचय देते हैं। इसलिए नहीं कि आप उपयोगकर्ता ऑब्जेक्ट स्विच करते हैं। इसलिए नहीं कि आप HTTP / HTML इंटरफ़ेस से SOAP या कमांड-लाइन इंटरफ़ेस पर माइग्रेट करते हैं।
आपके मामले में ACL एक कमांड तक पहुँच को नियंत्रित करता है, न कि कमांड को।
if($user->hasFriend($other_user) || $other_user->profileIsPublic()) $other_user->renderProfile()
(और प्रदर्शित करें, "आपके पास इस उपयोगकर्ता की प्रोफ़ाइल तक पहुंच नहीं है" या ऐसा कुछ नहीं है? मैं इसे प्राप्त नहीं करता हूं।