42

मैं Django रेस्ट फ्रेमवर्क का उपयोग कर एक एपीआई बना रहा हूं। बाद में इस एपीआई को आईओएस और एंड्रॉइड डिवाइसों द्वारा उपभोग किया जाना चाहिए। मैं अपने उपयोगकर्ताओं को फेसबुक और Google जैसे ओथ 2-प्रदाताओं के साथ साइन-अप करने की अनुमति देना चाहता हूं। इस मामले में, उन्हें अपने मंच के साथ एक खाता बनाना नहीं चाहिए। लेकिन उपयोगकर्ताओं को फेसबुक/Google खाता नहीं होने पर साइन-अप करने में भी सक्षम होना चाहिए, जिसके लिए मैं django-oauth-toolkit का उपयोग कर रहा हूं, इसलिए मेरे पास अपना स्वयं का oauth2-प्रदाता है।मैं पाइथन सोशल ऑथ के साथ Django OAuth Toolkit का उपयोग कैसे कर सकता हूं?

बाहरी प्रदाताओं के लिए मैं पाइथन-सोशल-ऑथ का उपयोग कर रहा हूं, जो ठीक काम करता है और स्वचालित रूप से उपयोगकर्ता ऑब्जेक्ट बनाता है।

मैं चाहता हूं कि ग्राहक बीयर टोकन का उपयोग करके प्रमाणीकृत करें, जो मेरे प्रदाता के साथ साइन अप करने वाले उपयोगकर्ताओं के लिए ठीक काम करता है (django-oauth-toolkit प्रमाणीकरण योजना और Django REST Framework के लिए अनुमति कक्षाएं प्रदान करता है)।
हालांकि, पायथन-सोशल-ऑथ केवल सत्र आधारित प्रमाणीकरण लागू करता है, इसलिए बाह्य oauth2 प्रदाता द्वारा पंजीकृत उपयोगकर्ताओं की ओर से प्रमाणित API अनुरोध करने का कोई सीधा तरीका नहीं है।

अगर मैं एक ACCESS_TOKEN कि Django-OAuth-टूलकिट द्वारा उत्पन्न किया गया है, एक अनुरोध कर रही है इस तरह से काम करता है का उपयोग करें:

curl -v -H "Authorization: Bearer <token_generated_by_django-oauth-toolkit>" http://localhost:8000/api/ 

हालांकि, निम्नलिखित काम नहीं करता है के बाद से वहाँ के लिए कोई इसी प्रमाणीकरण योजना है Django बाकी फ्रेमवर्क और सत्र-आधारित प्रमाणीकरण के लिए अजगर-सामाजिक लेखन केवल काम द्वारा प्रदान की AUTHENTICATION_BACKENDS:

curl -v -H "Authorization: Bearer <token_stored_by_python-social-auth>" http://localhost:8000/api/ 

अजगर-सामाजिक लेखन को प्रमाणित करने के बाद Django बाकी फ्रेमवर्क द्वारा प्रदान की ब्राउज़ करने योग्य API का उपयोग करके बस काम करता है ठीक है, सत्र कुकी के बिना केवल एपीआई कॉल काम नहीं करते हैं।

मुझे आश्चर्य है कि इस समस्या के लिए सबसे अच्छा तरीका क्या है। जिस तरह से मैं इसे देखता हूं, मेरे पास मूल रूप से दो विकल्प हैं:

ए: जब कोई उपयोगकर्ता बाहरी oauth2 प्रदाता (पायथन-सोशल-एथ द्वारा नियंत्रित) के साथ साइन अप करता है, तो oauth2_provider.models बनाने के लिए प्रक्रिया में हुक करें। एक्सेस टोकन और 'oauth2_provider.ext.rest_framework.OAuth2Authentication' का उपयोग करना जारी रखें, अब बाहरी प्रदाता के साथ पंजीकृत उपयोगकर्ताओं को प्रमाणित करना। इस दृष्टिकोण का सुझाव यहां दिया गया है: https://groups.google.com/d/msg/django-rest-framework/ACKx1kY7kZM/YPWFA2DP9LwJ

बी: एपीआई अनुरोध प्रमाणीकरण के लिए पायथन-सोशल-ऑथ का उपयोग करें। मैं अपने स्वयं के उपयोगकर्ताओं को एक कस्टम बैकएंड लिखकर और register_by_access_token का उपयोग करके पाइथन-सोशल-ऑथ में प्राप्त कर सकता हूं। हालांकि, चूंकि एपीआई कॉल Django सत्रों का उपयोग नहीं कर सकते हैं, इसका मतलब यह होगा कि मुझे Django Rest Framework के लिए प्रमाणीकरण योजना लिखनी होगी जो पायथन-सोशल-ऑथ द्वारा संग्रहीत डेटा का उपयोग करती है। ऐसा करने के तरीके पर कुछ संकेत यहां पाया जा सकता:
http://psa.matiasaguirre.net/docs/use_cases.html#signup-by-oauth-access-token
http://blog.wizer.fr/2013/11/angularjs-facebook-with-a-django-rest-api/
http://cbdev.blogspot.it/2014/02/facebook-login-with-angularjs-django.html
हालांकि, जिस तरह से मैं समझता हूँ कि यह अजगर-सामाजिक लेखन केवल जब एक लॉगिन कर टोकन पुष्टि करता है और Django सत्र पर निर्भर करता है बाद में। इसका मतलब यह होगा कि मुझे पाइथन-सोशल-एथ को प्रत्येक स्टेटलेस एपीआई अनुरोध के लिए पूरे ओथ 2-प्रवाह करने से रोकने और डीबी में संग्रहीत डेटा के खिलाफ जांच करने के लिए एक रास्ता खोजना होगा, जिसे वास्तव में पूछताछ के लिए अनुकूलित नहीं किया गया है जेएसओएन के रूप में संग्रहीत (मैं UserSocialAuth.objects.get (extra_data__contains =) का उपयोग कर सकता हूं)।
मुझे एक्सेस टोकन के दायरे को सत्यापित करने और उन्हें अनुमतियों की जांच करने के लिए भी उपयोग करना होगा, कुछ django-oauth-toolkit पहले से ही करता है (TokenHasScope, required_scopes आदि)।

फिलहाल, मैं विकल्प ए का उपयोग करने की ओर झुका रहा हूं, क्योंकि django-oauth-toolkit Django Rest Framework के साथ अच्छा एकीकरण प्रदान करता है और मुझे बॉक्स से बाहर की हर चीज मिलती है। एकमात्र कमी यह है कि मुझे अजगर-ओथ-टूलकिट के एक्सेसटोकन मॉडल में पाइथन-सोशल-ऑथ द्वारा पुनर्प्राप्त access_tokens को "इंजेक्ट" करना है, जो कि किसी भी तरह गलत लगता है, लेकिन शायद सबसे आसान तरीका होगा।

क्या किसी को ऐसा करने पर कोई आपत्ति है या शायद एक ही समस्या से अलग समस्या का सामना कर सकता है? क्या मुझे कुछ स्पष्ट याद आ रहा है और मेरी ज़िंदगी ज़रूरी ज़रूरी है? अगर किसी ने पहले ही पाइथन-सोशल-ऑथ और बाहरी ओथ 2 प्रदाताओं के साथ django-oauth-toolkit को एकीकृत किया है, तो मैं कुछ पॉइंटर्स या राय के लिए बहुत आभारी हूं।

उत्तर

79

OAuth को लागू करने में कठिनाई का एक बहुत कैसे समझ प्राधिकरण प्रवाह काम करने के लिए माना जाता है करने के लिए नीचे आता है। यह ज्यादातर इसलिए है क्योंकि यह लॉग इन करने के लिए "शुरुआती बिंदु" है, और जब किसी तीसरे पक्ष के बैकएंड (पायथन सोशल एथ जैसे कुछ का उपयोग करके) आप वास्तव में कर रहे हैं तो यह दो बार कर रहा है: एक बार आपके एपीआई के लिए और एक बार तीसरे के लिए -party एपीआई।

अपने एपीआई और एक तीसरे पक्ष के बैकएंड

प्रमाणीकरण प्रक्रिया का उपयोग कर अनुरोध है कि आप के माध्यम से जाने की जरूरत है को अधिकृत करना है:

Sequence diagram for option A

Mobile App -> Your API : Authorization redirect 
Your API -> Django Login : Displays login page 
Django Login -> Facebook : User signs in 
Facebook -> Django Login : User authorizes your API 
Django Login -> Your API : User signs in 
Your API -> Mobile App : User authorizes mobile app 

मैं उपयोग कर रहा हूँ "फेसबुक" यहां तीसरे पक्ष के बैकएंड के रूप में, लेकिन प्रक्रिया किसी भी बैकएंड के लिए समान है।

अपने मोबाइल एप्लिकेशन के परिप्रेक्ष्य, आप केवल Django OAuth टूलकिट द्वारा प्रदान की /authorize यूआरएल रीडायरेक्ट कर रहे हैं से

। वहां से, मोबाइल ऐप प्रतीक्षा करता है जब तक कि कॉलबैक यूआरएल तक पहुंच न जाए, बस मानक ओएथ प्रमाणीकरण प्रवाह की तरह। लगभग हर चीज (Django लॉगिन, सामाजिक लॉगिन, आदि) पृष्ठभूमि में Django OAuth Toolkit या पायथन सोशल ऑथ द्वारा संभाला जाता है।

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

Option A without a third-party backend

Mobile App -> Your API : Authorization redirect 
Your API -> Django Login : Displays login page 
Django Login -> Your API : User signs in 
Your API -> Mobile App : User authorizes mobile app 

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

Sequence diagram with your API as the gatekeeper

Mobile App -> Your API : Authorization redirect 
Your API -> Mobile App : Receives OAuth token 
Mobile App -> Your API : Requests the display name 
Your API -> Facebook : Requests the full name 
Facebook -> Your API : Sends back the full name 
Your API -> Mobile App : Send back a display name 

अन्यथा, OAuth क्लाइंट अपने एपीआई बाईपास और अनुरोधों तीसरे पक्ष के एपीआई को अपनी ओर पर बनाने के लिए सक्षम नहीं होगा।

Sequence diagram for bypassing your API

Mobile App -> Your API : Authorization redirect 
Your API -> Mobile App : Receives Facebook token 
Mobile App -> Facebook : Requests all of the followers 
Facebook -> Mobile App : Sends any requested data 

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

अपने एपीआई के लिए अनुरोध प्रमाणित कर रहा है

मोबाइल अनुप्रयोग का उपयोग करता है तो अपने OAuth टोकन अपने एपीआईलिए अनुरोध करने के लिए, प्रमाणीकरण के सभी में Django OAuth टूलकिट (या अपनी OAuth प्रदाता) के माध्यम से होता है पृष्ठभूमि। आप सभी को देखते हैं कि आपके अनुरोध से जुड़े User हैं।

How OAuth tokens are validated

Mobile App -> Your API : Sends request with OAuth token 
Your API -> Django OAuth Toolkit : Verifies the token 
Django OAuth Toolkit -> Your API : Returns the user who is authenticated 
Your API -> Mobile App : Sends requested data back 

यह महत्वपूर्ण है, यदि उपयोगकर्ता फेसबुक या Django के प्रमाणीकरण प्रणाली से आ रही है क्योंकि प्राधिकरण चरण के बाद यह एक फर्क नहीं करना चाहिए। आपके एपीआई को काम करने के लिए सिर्फ User की आवश्यकता है, और आपका ओएथ प्रदाता टोकन के प्रमाणीकरण और सत्यापन को संभालने में सक्षम होना चाहिए।

सत्र-समर्थित प्रमाणीकरण का उपयोग करते समय Django REST ढांचे उपयोगकर्ता को प्रमाणीकृत करने से यह बहुत अलग नहीं है।

Sequence diagram for authenticating using sessions

Web Browser -> Your API : Sends session cookie 
Your API -> Django : Verifies session token 
Django -> Your API : Returns session data 
Your API -> Django : Verifies the user session 
Django -> Your API : Returns the logged in user 
Your API -> Web Browser : Returns the requested data 

फिर, यह सब Django OAuth टूलकिट द्वारा नियंत्रित किया जाता है और लागू करने के लिए अतिरिक्त काम की आवश्यकता नहीं है।

एक देशी एसडीके

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

इसका कारण यह है अपने सर्वर लॉगिन मान्य नहीं कर सकता और करने के लिए मजबूर कर रहा है मान लेते हैं कि लॉगिन मान्य और वास्तविक है, जिसका अर्थ है कि यह किसी भी और सभी सुरक्षा कि अजगर सामाजिक प्रमाणीकरण प्रदान करती है नजरअंदाज।

Using a native SDK can cause issues

Mobile App -> Facebook SDK : Opens the authorization prompt 
Facebook SDK -> Mobile App : Gets the Facebook token 
Mobile App -> Your API : Sends the Facebook token for authorization 
Your API -> Django Login : Tries to validate the token 
Django Login -> Your API : Returns a matching user 
Your API -> Mobile App : Sends back an OAuth token for the user 

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

+0

हाय केविन, आपके उत्तर के लिए बहुत बहुत धन्यवाद। मैंने शायद इसे पर्याप्त स्पष्ट नहीं किया है, लेकिन मैं जो करना चाहता हूं वह है कि मेरे उपयोगकर्ताओं को फेसबुक या Google जैसे प्रदाताओं का उपयोग करके साइन-अप करने की क्षमता प्रदान करें, जैसे स्टैक ओवरफ्लो करता है। मैं इन प्रदाताओं से कोई अन्य जानकारी प्राप्त नहीं करना चाहता हूं, केवल उपयोगकर्ताओं को उनके साथ लॉगिन करने की अनुमति देता हूं। अगर वे उदा। Google, उन्हें मेरे प्रदाता के साथ पंजीकरण करने की आवश्यकता नहीं है। प्रॉक्सी की तरह django-oauth-toolkit का उपयोग करने के लिए आपका सुझाव बहुत समझ में आता है, मुझे इसे सोचने की ज़रूरत है और बाद में आपसे मिल जाएगी। – jeverling

+0

केवल एक एपीआई है और django-oauth-toolkit को साइन-अप करने के लिए अलग-अलग विकल्पों में से एक माना जाता है, हां। मैंने केवल साइन-अप के लिए बाहरी प्रदाताओं की पेशकश करने के बारे में सोचा था, लेकिन उन उपयोगकर्ताओं को पसंद करेंगे जिनके पास Google या Facebook के साथ कोई खाता नहीं है या आप साइन-अप करने के लिए इसे अपने प्लेटफॉर्म से संबद्ध नहीं करना चाहते हैं। – jeverling

+0

यह काम करना चाहिए, लेकिन इस मामले में मुझे अभी भी समस्या है कि एपीआई कॉल कैसे करें उदाहरण के साथ एक कुकी-जार की तरह कुछ उपयोग किए बिना एक आईओएस ऐप। Django-oauth-toolkit के साथ मैं सिर्फ एक भालू टोकन के साथ प्राधिकरण शीर्षलेख का उपयोग कर सकता हूं, जो अभी 'पायथन-सोशल-ऑथ' के साथ संभव नहीं लगता है। – jeverling

8

मैंने इसे आपके ए विकल्प का उपयोग करके हल किया।

मैं जो करता हूं वह उन उपयोगकर्ताओं को पंजीकृत करता है जो तीसरे पक्ष का उपयोग अपने तीसरे पक्ष के पहुंच टोकन द्वारा साइन अप करने के लिए करते हैं।

url(r'^register-by-token/(?P<backend>[^/]+)/$', 
    views.register_by_access_token), 

इस तरह, मैं इस तरह एक GET अनुरोध जारी कर सकते हैं:

GET http://localhost:8000/register-by-token/facebook/?access_token=123456

और register_by_access_token कहा जाता हो जाता है। request.backend.do_auth टोकन से उपयोगकर्ता की जानकारी के लिए प्रदाता से पूछताछ करेगा और यदि वह पहले से पंजीकृत है तो उपयोगकर्ता में जानकारी या साइन इन के साथ उपयोगकर्ता खाते को जादुई रूप से पंजीकृत करें।

फिर, मैं मैन्युअल रूप से एक टोकन बनाता हूं और क्लाइंट को मेरी एपीआई पूछने के लिए इसे JSON के रूप में वापस कर देता हूं।

from oauthlib.common import generate_token 
... 
@psa('social:complete') 
def register_by_access_token(request, backend): 
    # This view expects an access_token GET parameter, if it's needed, 
    # request.backend and request.strategy will be loaded with the current 
    # backend and strategy. 
    third_party_token = request.GET.get('access_token') 
    user = request.backend.do_auth(third_party_token) 

    if user: 
     login(request, user) 

     # We get our app! 
     app = Application.objects.get(name="myapp") 

     # We delete the old token 
     try: 
      old = AccessToken.objects.get(user=user, application=app) 
     except: 
      pass 
     else: 
      old.delete() 

     # We create a new one 
     my_token = generate_token() 

     # We create the access token 
     # (we could create a refresh token too the same way) 
     AccessToken.objects.create(user=user, 
            application=app, 
            expires=now() + timedelta(days=365), 
            token=my_token) 

     return "OK" # you can return your token as JSON here 

    else: 
     return "ERROR" 

मुझे बस टोकन उत्पन्न करने के तरीके के बारे में निश्चित नहीं है, क्या यह अच्छा अभ्यास है? खैर, मतलब समय में, यह काम करता है !!

+0

कहां, या बेहतर: आप access_token कैसे प्राप्त करते हैं? कौन भेजता है? मैं उपग्रह निर्माता का उपयोग कर रहा हूं और मैं बहुत संघर्ष कर रहा हूं। – Igor

+0

आपको अपने फ्रंट एंड से एक्सेस टोकन मिलता है। एक आईओएस ऐप और फेसबुक के लिए, यह फेसबुक आईओएस एसडीके –

+0

होगा बहुत बहुत धन्यवाद। – Igor

4

शायद जो आप खोज रहे हैं वह है। यह पैकेज python-social-auth और django-oauth-toolkit पर निर्भर करता है, जिसका आप पहले से उपयोग करते हैं। मैंने दस्तावेज़ों के माध्यम से जल्दी से स्कैन किया, और ऐसा लगता है कि आप जो करने की कोशिश कर रहे हैं उसे लागू करना है।

+1

यह अब तक का सबसे अच्छा विकल्प है। इसका परीक्षण किया और यह बहुत अच्छा काम करता है! –

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