2016-03-21 12 views
5

मैं पहले से ही डीजेंगो आराम ऑथ टोकन में बिल्डिंग का उपयोग कर रहा हूं और मैं एक अन्य एपीआई रिलीज करने की योजना बना रहा हूं जिसे मेरे Django एप्लिकेशन में कुछ कार्रवाई करने के लिए बाहरी एकीकरण द्वारा बुलाया जाएगा। मुद्दा यह है कि मैं इस बाहरी एपीआई कॉल के लिए एक अन्य टोकन उत्पन्न करना चाहता हूं जो कि ऑथ सिस्टम से अलग होना चाहिए (f.i. जैसे मंडल एपीआई कुंजी या गिथब पर्सनल एक्सेस टोकन)। क्या यह Django आराम ढांचे authtoken मॉडल से एपीआई कुंजी उत्पन्न करने का एक अच्छा समाधान है?एपी कुंजी और डैंजो रेस्ट फ्रेमवर्क ऑथ टोकन

बाहरी api टोकन:

  • समय सीमा समाप्त नहीं करना चाहिए (यह एक सत्र प्रमाणन प्रणाली में समाप्त हो सकता है)
  • उपयोगकर्ता से जुड़ा हुआ जा सकता है, लेकिन नहीं की आवश्यकता है (यदि खाते से लिंक)
  • रद्द किया जा सकता है और

क्या आपके पास एपीआई कुंजी जारी करने का कोई अनुभव है?

क्या यह Django Rest Framework द्वारा अनुशंसित कोई भी सर्वोत्तम अभ्यास है?

धन्यवाद;)

+0

आप साझा कर सकते हैं कि तुम क्या खत्म किया कर रही? मैं एक ही बाधाओं का सामना कर रहा हूं .. –

+0

बस मेरे कोड को उत्तर के रूप में प्रकाशित किया गया http://stackoverflow.com/a/38913644/2551769 – jsan

उत्तर

7

बिल्ड-इन टोकन व्यवहार पर दुष्प्रभाव से बचने के लिए मैंने एक नया प्रमाणीकरण बैकएंड और एक नया टोकन मॉडल बनाया है।

models.py

class ApiKeyToken(models.Model): 
    key = models.CharField(max_length=40, primary_key=True) 
    company = models.ForeignKey(Company) 
    is_active = models.BooleanField(default=True) 

    def save(self, *args, **kwargs): 
     if not self.key: 
      self.key = self.generate_key() 
     return super(ApiKeyToken, self).save(*args, **kwargs) 

    def generate_key(self): 
     return binascii.hexlify(os.urandom(20)).decode() 

    def __unicode__(self): 
     return self.key 

authentication.py

class ApiKeyAuthentication(TokenAuthentication): 

    def get_token_from_auth_header(self, auth): 
     auth = auth.split() 
     if not auth or auth[0].lower() != b'api-key': 
      return None 

     if len(auth) == 1: 
      raise AuthenticationFailed('Invalid token header. No credentials provided.') 
     elif len(auth) > 2: 
      raise AuthenticationFailed('Invalid token header. Token string should not contain spaces.') 

     try: 
      return auth[1].decode() 
     except UnicodeError: 
      raise AuthenticationFailed('Invalid token header. Token string should not contain invalid characters.') 

    def authenticate(self, request): 
     auth = get_authorization_header(request) 
     token = self.get_token_from_auth_header(auth) 

     if not token: 
      token = request.GET.get('api-key', request.POST.get('api-key', None)) 

     if token: 
      return self.authenticate_credentials(token) 

    def authenticate_credentials(self, key): 
     try: 
      token = ApiKeyToken.objects.get(key=key) 
     except ApiKeyToken.DoesNotExist: 
      raise AuthenticationFailed('Invalid Api key.') 

     if not token.is_active: 
      raise AuthenticationFailed('Api key inactive or deleted.') 

     user = token.company.users.first() # what ever you want here 
     return (user, token) 

तो फिर तुम साथ सुरक्षित एपीआई अनुरोध कर सकते हैं:

curl http://example.com/api/your-awesome-api.json -H "Authorization: Api-Key {token}" 
+0

क्या समय-समय पर समाप्ति के साथ टाइमस्टैम्प होना बेहतर होगा और टोकन को स्वचालित रूप से एक बार में नवीनीकृत करना बेहतर नहीं होगा? या क्या आपके उपयोग के मामले में इसकी आवश्यकता नहीं है? –

+0

मुझे अपने मामले में केवल एक स्थायी एपीआई कुंजी की आवश्यकता है। – jsan

2

अगर मैं तुम्हें सही ढंग से समझ है, तो Json Web Tokens अपनी आवश्यकताओं के लिए समाधान है। एक बहुत अच्छा django पैकेज उपलब्ध है जो django आराम ढांचे के साथ आसानी से एकीकृत करता है: django-rest-framework-jwt

इस पैकेज आप

  1. सेट कर सकते हैं सीमा समाप्ति समय
  2. सक्रिय करें या वापस ले कुंजी
  3. अपने एपीआई के लिए हर बाहरी कॉल से निर्धारित करते हैं, यदि टोकन मान्य है साथ

अभी भी

आशा है कि मदद करता है।

+0

मुझे django-rest-framework-jwt में कोई भी निरसन और पुनः सक्रिय व्यवहार नहीं मिला है। Django आराम 'euthtoken' की तुलना में मूल्य कहां है? – jsan

+0

यह इस बात पर निर्भर करता है कि आप वास्तव में क्या करना चाहते थे। एक समाधान अनुरोध हेडर से जेसन वेब टोकन को हटाना होगा। और आवश्यकता होने पर इसे फिर से जोड़ें। – niklas

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