Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-tastypie: why are api keys useful and how to support multiple auth schemes?

I'm designing a website in which people will sign on as users and potentially be in multiple groups, which come in a couple of different types. I wanted to both have a website that people can use directly, as well as expose an API that can be consumed by other websites.

What's the best way to implement a login system that works both for regular users of the site itself, as well as which allow API-consuming websites to seamlessly create an account on behalf of the user and allow the user to view their data both from my website and the API-consuming website?

I'm using Django 1.5, so I'm willing to customize the user model and all that. The API will be furnished using Tastypie.

EDIT: Honestly, my main problem is that I don't really understand when API keys are useful and how they coexist (if they do) with regular user logins.

like image 407
Platinum Azure Avatar asked Jul 07 '13 03:07

Platinum Azure


People also ask

Is API key enough for authentication?

API keys can identify a project to an API and specify which resources a project may access. However, experts do not consider API keys to be secure enough on their own. This is for a few reasons: API keys can't authenticate the individual user making the request, only the project or application sending the request.

How does API Key authorization work?

API keys provide project authorizationBy identifying the calling project, you can use API keys to associate usage information with that project. API keys allow the Extensible Service Proxy (ESP) to reject calls from projects that haven't been granted access or enabled in the API.

What is the most secure way to transmit API key?

Always use TLS Every web API should use TLS (Transport Layer Security). TLS protects the information your API sends (and the information that users send to your API) by encrypting your messages while they're in transit. You might know TLS by its predecessor's name, SSL.

What is Django Tastypie?

¶ Tastypie is a webservice API framework for Django. It provides a convenient, yet powerful and highly customizable, abstraction for creating REST-style interfaces. Using Tastypie With Non-ORM Data Sources. Resources.


1 Answers

Use case:

The first and use case for API keys is automation. You provide your api key (or commonly called token) to a 3rd party and voila, you can have the 3rd party do stuff for you. When you do not trust the 3rd party anymore, you can just revoke the api key or re-generate it. Api keys allow the user to initiate & authenticate the chain of actions by requesting the token via traditional authentication (e.g username/password), and then the user passes it on to the interested parties. See my little story about phone numbers at the end.

Why not use passwords?

Because you don't want to compromise your users on other websites and have them type their password there in order to use your APIs. If the 3rd party is compromised, then the user's communications or password are compromised.

Here are good resources:

  • What is token based authentication?
  • https://developers.google.com/google-apps/sso/saml_reference_implementation
  • Tastypie APIKey authentication
  • Django Tastypie: How to Authenticate with API Key

Api keys with tastypie

Here is a good starting point:

from django.contrib.auth.models import User
from django.db import models
from tastypie.models import create_api_key
models.signals.post_save.connect(create_api_key, sender=User)

This should take care of creating api keys thanks to the post_save signal. The second part is to allow more than one scheme for the authentication to fit your use case, so... onto MultiAuthentication:

from django.contrib.auth.models import User
from tastypie.authentication import BasicAuthentication, ApiKeyAuthentication, MultiAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.resources import ModelResource

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'auth/user'
        excludes = ['email', 'password', 'is_superuser']

        authentication = MultiAuthentication(BasicAuthentication(), ApiKeyAuthentication())
        authorization = DjangoAuthorization()

Other considerations

These are good practice to never leak sensitive data on the network:

  • do not do any user/password authentication without ssl or tls.
  • never use http basic authentication without ssl or tls.
  • lock down resources users shouldn't access to with permissions.
  • make sure your responses have correct cache-control headers
  • always allow users to reset/regenerate/delete their tokens / api keys.
  • a user need not have only one api key, you can have several of them; one for each 3rd party.

I use gmail so here is an example from https://security.google.com/settings/security (review permissions) where I can see how google openid is used:

revoking permissions for google openid

Why should you use one api key for each 3rd party? is the same as why should you allow the user to have more than one api key and label them for a particular use?.

The answer is that if the api key is something you share just like your phone number, but you don't need to give the same phone number to all your friends (google voice FTW!).

  • case 1: one phone number.

If your friend misbehaves and gives it to a bunch of sales rep, you are going to be pretty annoyed. If your phone is the same, then whoever has it may share it with somebody else without your knowing. End results, all sales reps know your number... not so good. But you still want your mom to be able to call you, right? So you can't really change your number. Now imagine a more dangerous situation; you have a tab at the local pizzeria, and they know you by name / phone number. If someone gets your api key, they may impersonate you to order pizza and still charge you (you have a tab!).

  • case 2: multiple phone numbers:

If you have 100 numbers to you give to 100 different friends, not only can they contact you, but if a sales rep calls you on a particular number, you would know which of your friend gave it away and you can just cut that one number. Mom's now happy because she can tell you where to go for brunch. Your friend now decides to order pizza ... you can now trace it to your friend (or you should provide the pizzeria a number that none of your friend knows).

like image 103
5 revs Avatar answered Nov 02 '22 07:11

5 revs