Setting up Django Piston with OAuth Support

django-piston is a mini framework for creating REST APIs. One of the big reasons to use django-piston rather than rolling your own framework is that it supports OAuth authentication “out of the box.” Unfortunately, documentation on how to enable OAuth authentication is largely lacking. Here are the steps I went through to fully hook up OAuth support in my django-piston powered REST API.

  1. Add piston to installed apps and run syncdb
    This step isn’t necessary when using piston without OAuth support. However, if you want OAuth support, piston defines a few models that are needed to keep track of the OAuth tokens and consumer keys. Adding piston to INSTALLED_APPS will register these models.
  2. Add an oauth challenge template at oauth/challenge.html
    For some reason, this template does not come with django-piston. When an unauthenticated request is made to an API protected by OAuth, the contents of this template will be returned. In theory, the template should describe what OAuth is and how a client programmer can get access to the API using OAuth. In practice it doesn’t really matter what you put there, you just have to have the file to avoid TemplateNotFound exceptions.
  3. Hook up OAuth token urls
    OAuth requires the web service to provide three urls through which OAuth can aquire the proper tokens and authorize a user. Piston provides views for these functions which will create the proper tokens and integrate with Django’s auth framework. Here is how my url conf looks:

    urlpatterns = patterns(
        'piston.authentication',
        url(r'^oauth/request_token/$','oauth_request_token'),
        url(r'^oauth/authorize/$','oauth_user_auth'),
        url(r'^oauth/access_token/$','oauth_access_token'),
    )
          
  4. Add an authorization template at piston/authorize_token.html
    This template is for the page the user will be directed to when they authorize the client application. It should be a simple form asking the user to confirm that they want to give the requesting application access to their data. Piston actually comes with this template but it unfortunately lacks a submit button! You also want to write your own template so that it can be better integrated with the look and feel of your site. Just to get things going, here is a sample that works:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <title>Authorize Token</title>
      </head>
      <body>
        <h1>Authorize Token</h1>
    
        <form action="{% url piston.authentication.oauth_user_auth %}" method="POST">
          {{ form.as_table }}
          <button type="submit">Confirm</button>
        </form>
    
      </body>
    </html>
          

    If you want to further customize how this particular page works, you can specify an OAUTH_AUTH_VIEW setting to tell piston which view to use. For example:

    OAUTH_AUTH_VIEW = 'api.views.oauth.authorize_oauth'
    

    You’ll want to take a look at piston.authentication.oauth_auth_view as a reference when writing your own view.

  5. Add your first OAuth consumer!
    You can either do this programatically in the shell, or using django’s admin interface. If using the admin interface, you’ll have to register the piston.models.Consumer model with the admin.

I’ve had OAuth up and running now for a few days and am very glad that users will no longer have to give API clients their username and password to access their private data. It was a bit of a pain to set up but I think it’s worth it.

About these ads
22 comments
  1. Mauro said:

    Great tutorial, thanks!
    My problem now is that I don’t know how OAuth works, so idk how a user can use the API!
    The managers.py file in the piston dir looks promise to add/manage the users, but I’m not sure that I understand how to use this managers… Can you suggest me a good (basic) tutorial on OAuth and/or how to use it with Piston?
    Thanks a lot for your help!

  2. Eric said:

    Does this not have any dependencies? I’ve been trying to set up my own OAuth API with django-oauth, but if Piston has already done all of this, I’ll be using piston

  3. Piston does not have any dependencies other than Django itself.

  4. Unfortunately OAuth has a pretty steep learning curve. I’ve recently been playing with OAuth 2, the newer OAuth specification and it is about a million times easier to use. At this point I think Facebook is the only major site to implement OAuth 2 for API authentication, but I’m looking forward to seeing more sites use OAuth 2.

    There aren’t really any good tutorials that I’ve found for understanding how OAuth works behind the scenes. The documentation at oauth.net mostly covers the frontend workflow experience and doesn’t get into that many implementation details. For the details, you really just have to read the specification: http://tools.ietf.org/html/rfc5849

    If you are building out an API from scratch now, I would seriously consider using Oauth 2, especially if you can deal with putting your API behind ssl. Writing OAuth 2 clients is so simple that you don’t have to worry about the lack of client libraries. Piston does not support OAuth 2 right out of the box, but it would be relatively straightforward to implement.

  5. Hi, firstly a great tutorial to django-piston. I’m hhitting an issue that a few other people seem to also be experiencing. I was wondering whether you might know how to resolve it?

    Essentially when i go to the /access_token/ URL to grant my test user acces. I tick the checkbox and then click submit but the resulting page throws up a “oauth_user_auth() takes exactly 1 argument (2 given)” error. Looking at the code it seems that in line 213 of piston/authentication.py a call to the oauth_user_auth method expects just one parameter. The obvious thought here is that one simply needs to alter pistons authentication.py to pass just one parameter. However, as this would mean altering piston directly and given that your tutorial suggests that everything should work out of the box, I was wondering whether i was just doing something wrong.

    Have you by any chance come across this error before and are you able to offer any guidance?

    Also, line 213 calls the OAUTH_CALLBACK_VIEW view stored in settings.py. Based on tutorials I have seen this is the same method that line 213 is called FROM… so even if i remove the second parameter it just loops round and round. I’m wondering whether this is where i have gone wrong. Perhaps i am referencing the wrong view in the OAUTH_CALLBACK_VIEW setting. What do you have yours set to?

  6. Hi Roel,

    Thanks, that solution looks spot on.

  7. Roel said:

    Benjamin,

    did you manage to get it all up and running? I did, but i don’t know how to continue. I can get the needed tokens.. but i don’t know how to access a protected resource.

  8. Hi Roel,

    Actually, as chance would have it, my client has since asked to scrap oauth implementation so I have not yet had an opportunity to put your solution to the test.

  9. Ricardo Machado said:

    Roel,

    I’m with the same problem as yours. I have the tokens but I don’t know how can I access to a protected resource.
    I’m trying with Authorization Header, but till now I had no success.

  10. Kevin said:

    Hi Roel,

    Having a good RESTFul API with a good authentication system is great.
    I have a running website developped with Django. It’s working great so far without Piston and with Django own authentication system, event when most of the request are POST and GET with JSON object (lot’s of AJAX).

    I want to add support for iPhone and Android apps on my Django server. I can’t use the built-in Django Auth system because csrf_token mess things up! I then thought about using OAuth for doing SmartPhone authentication :-). my problem is that with Piston, it seems that you are force to use HTML TEMPLATE with authentication challenge and so forth ?

    Is there a way to use OAuth without HTML TEMPLATE but only like JSON response ?

    Thanks a lot

    Kevin

  11. Gabriel Novaes said:

    Hi,

    Google Post.

    Do you have a app implemented in this post?

    Can you send me?

    regards

  12. Diego said:

    Do you have the code for this particular example?

  13. Andy said:

    hi,

    as a django and piston newbie i’m struggling with the same problems as the guys above!
    -> i can run my own views and templates, but i don’t really know how to implement a webservice using piston with OAuth
    -> get/return data after sucessfull authentication

    has anybody a fully working webservice (OAuth) as an example or similar? ..

    br,
    andy

  14. nico said:

    I’ve managed to get the authentication to work, however it seems only to work for 1 of my two handlers. Whenever I try post data to the second handler the token doesn’t work. Do you have any advice on how I would be able to fix this?

  15. Alysa said:

    Excellent beat ! I wish to apprentice while you amend your
    website, how could i subscribe for a blog web site?
    The account aided me a acceptable deal. I had
    been a little bit acquainted of this your broadcast offered bright clear concept

  16. Great web site you have here.. It’s difficult to find high quality
    writing like yours nowadays. I seriously appreciate individuals like you!
    Take care!!

  17. Whats up are using WordPress for your site platform? I’m new to the
    blog world but I’m trying to get started and create my own.
    Do you need any html coding expertise to make your own blog?
    Any help would be greatly appreciated!

  18. Thanks for the good writeup. It in truth was a
    enjoyment account it. Look advanced to more brought agreeable from you!
    By the way, how could we keep up a correspondence?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 76 other followers

%d bloggers like this: