Api key and Django Rest Framework Auth Token

I already use the built-in Django rest authentication token, and I plan to release another api that will be called by external integration in order to trigger some actions in my Django application. The problem is that I want to create another token for this external api call, which should be separated from the auth system (for example, as Mandrill APIs or Github's personal token). Is this a good solution for generating api keys from the framework of the Django rest authtoken Model?

External Token api:

  • never expires (it may expire in an auth session system)
  • can be attached to the user, but not required (if it is associated with an account)
  • can be recalled and activated.

Do you have experience in issuing api keys?

Is this the best practice recommended by the Django Rest Framework?

Thanks;)

+5
source share
2 answers

I created a new authentication server and a new token model to avoid the side effect when working with the inline token.

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) 

Then you can request secure api with:

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

If you understand correctly, then Json Web Tokens is the solution for your needs. There is a really nice django package that seamlessly integrates with the django leisure map: django-rest-framework-jwt .

With this package you can

  • set expiration time
  • reactivate or cancel key
  • determine from any external call of your api if the token is valid

Yet

Hope this helps.

+2
source

Source: https://habr.com/ru/post/1245493/


All Articles