2015-08-18 14 views
5

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

मेरे पास एक मॉडल है (उदा। project) जिसमें मेरे पास कुछ जानकारी है (उदा। नाम, वर्णन) जिसे कुछ भूमिकाओं द्वारा संशोधित किया जा सकता है (उदा। admin)। लेकिन साथ ही अन्य भूमिकाएं भी हैं (उदा। worker) जो उस मॉडल के अंदर उस जानकारी को संशोधित करने में सक्षम नहीं होनी चाहिए लेकिन फिर भी कुछ अन्य जानकारी (जैसे प्रारंभिक और अंतिम तिथियां) को संशोधित कर सकती है।

मैंने इस मुद्दे के लिए दो समाधान सोचा है। पहला अनुरोध HTTP अनुरोध को पढ़ रहा है और अनुरोध के आधार पर किए जाने वाले कार्यों को परिभाषित कर रहा है। इसका मतलब यह है कि प्रत्येक बार जब मॉडल में एक नया फ़ील्ड जोड़ा जाता है, तो मुझे इस तर्क को संशोधित करना होगा। यह बनाए रखने के लिए बहुत मुश्किल लगता है, त्रुटि प्रवण है और कमजोरियों को पेश कर सकते हैं।

दूसरी ओर, मैंने सोचा है कि मैं मॉडल को दो अलग-अलग मॉडल में विभाजित कर सकता हूं। उनमें से एक डेटा जिसमें केवल एक भूमिका है (admin) संशोधित कर सकता है और दूसरा अन्य डेटा को परिभाषित कर सकता है जिसे दोनों भूमिकाओं द्वारा संशोधित किया जा सकता है (admin, worker)। इस तरह, मुझे HTTP अनुरोध को पार्स नहीं करना पड़ेगा, क्योंकि अगर मुझे पहले मॉडल को प्रभावित करने वाला POST/PUT अनुरोध मिलता है और उपयोगकर्ता की कार्यकर्ता भूमिका होती है तो मैं इसे सीधे अस्वीकार कर सकता हूं।

यह स्थिति एक से अधिक मॉडल के साथ होती है।

मैं जानना चाहता हूं कि जाने का कोई डिफ़ॉल्ट तरीका है या मैं पहिया को फिर से शुरू कर रहा हूं। मुझे लगता है कि यह स्थिति वास्तव में आम होनी चाहिए। उदाहरण के लिए, मैं एक गिट प्रोजेक्ट के बारे में सोच सकता हूं जिसमें कुछ उपयोगकर्ताओं को एक परियोजना के अंदर एक चीज करने की सुविधा है लेकिन दूसरों को नहीं।

पूरक नोट्स (प्रतिक्रिया वास्तव में सराहना की जाएगी):

  • मैं सबसे शायद भूमिकाएं और अनुमतियां लागू करने के लिए django-role-permissions मॉड्यूल का उपयोग करेगा। मैं django अंतर्निहित समूहों का उपयोग नहीं कर सकता क्योंकि, हालांकि आप उन्हें अनुमतियां जोड़ सकते हैं, मैं उन्हें समूह उपयोगकर्ताओं (रोल के साथ कुछ भी करने के बिना) का उपयोग करूंगा।

  • मैं अनुमति फ़ाइल में भूमिकाओं और अनुमतियों (स्ट्रिंग आधारित अनुमति, जैसे create_project, modify_project_description) के बीच संबंध बनाएगा।

  • प्रत्येक अनुरोध प्राप्त करते समय मैं जांच करूंगा कि कौन सी भूमिकाओं में उस क्रिया को करने के लिए विशेषाधिकार हैं और जांचें कि क्या उपयोगकर्ता उन भूमिकाओं में से कोई है (गतिविधि आधारित प्राधिकरण, इसका मतलब है कि अंत में मैं गतिविधि/क्रिया की जांच करूंगा भूमिका के)।

उत्तर

1

कुछ विचार देने के बाद मुझे दो समाधान मिले।

पहला समाधान था (जैसा कि मैंने प्रश्न में उल्लिखित मॉडल को विभाजित करने की बजाय) प्रत्येक प्रकार की कार्रवाई के लिए अलग-अलग अंतराल (यूआरएल) घोषित किया था। फिर प्रत्येक एंडपॉइंट serializer में fields क्लास वेरिएबल के माध्यम से मान्य पैरामीटर को परिभाषित करना।

इसका मतलब है कि यदि एक भूमिका केवल कुछ फ़ील्ड अपडेट कर सकती है, तो मैं इस क्रिया के लिए ModelViewSet बनाउंगा और इस मॉडलव्यूसेट से संबंधित serializer कक्षा में केवल कुछ पैरामीटर की अनुमति होगी।

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

दूसरा (और चुने हुए) समाधान किसी अनुमति/भूमिका तालिका जिसमें आप अंत बिंदु जहां कार्रवाई होने के लिए (अगर आप सही तरीके से अपने आवेदन का निर्माण किया है यह सिर्फ ModelViewSet हो सकता है परिभाषित परिभाषित करने के लिए था वर्ग का नाम), क्रिया को निष्पादित करने की क्रिया (सूची, पुनर्प्राप्ति, निर्माण ...) संबंधित मॉडल के फ़ील्ड जिन पर बातचीत की जा सकती है और वह भूमिका जो उन क्षेत्रों के साथ बातचीत कर सकती है।

मैं अनुमति तालिका के लिए उपयोग की गई डेटा संरचना के रूप में शब्दकोशों का उपयोग करने का सुझाव दूंगा ताकि प्रत्येक अनुमति जांच O(1) हो।

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

मैंने ModelSetView कक्षा में check_permissions() विधि को ओवरराइड करके अनुमति जांच लागू की। सावधान रहें और वहां भी मूल check_permissions() कार्यक्षमता रखें।

2

लगता है जैसे आप कुछ फ़ील्ड स्तर की सुरक्षा चाहते हैं। प्रतिबंधित उपयोगकर्ताओं के लिए फ़ील्ड के सीमित सेट तक पहुंच पहुंचने के लिए आप प्रॉक्सी मॉडल का उपयोग कर सकते हैं।

एक और विकल्प कस्टम सीरिएलाइज़र क्लास का उपयोग करना हो सकता है जो कुछ क्षेत्रों में केवल पढ़ने के लिए लागू होता है। व्यूसेट सबक्लास पर get_serializer पिवट करने के लिए एक अच्छी जगह हो सकती है, आपको वर्तमान उपयोगकर्ता को self.request.user में ढूंढना चाहिए।

+1

आप एक उपरोक्त के लायक हैं क्योंकि मैं आपके द्वारा उल्लेख की गई सभी चीजों को लागू करने के लिए समाप्त होता हूं (प्रॉक्सी मॉडल से अलग)। – newlog

संबंधित मुद्दे