APIs, Development, Django, Mobile, Security

API Authentication Django and Android Apps

Django API Authentication for android and ios mobile apps Django API Authentication for android and ios mobile apps

Client and User API Authetication for Django, Android and iOS apps

While working on a recent project, I found myself in a situation where me and my team had to implement the security authentication layer on the server side to make sure only the authenticated client applications (android and iOS mobile apps in our case) and authenticated users have access to the data. As anybody else would, we started to research on the best practices and how other people in the industry have implemented such authentication.

We had used Django Rest Framework to implement our API resources and as it is one of the most known/used packages to implement APIs with Django Framework, I thought we would easily find the information we are looking for. But to my surprise all our google searches ended up in blogs and stackoverflow answers that showed how to implement authentication, which we already had an idea about.

We could not find a single example that showed us how these authentication would work with different types of clients e.g. web, android & ios. Once we failed in gathering the information we required, we decided to identify our core requirements and come-up with the best possible solution for us.

We had only 2 major requirements:

  • Client Authentication – Only allow our own clients (web and mobile apps) to access the APIs.
  • User Authentication – Only allow authenticated users to access the APIs.

Client Authentication

We wanted to make sure that only our own mobile apps are allowed to use our API end points and most of the examples in our research just showed implementation of authentication for users we knew we’d need to work more on this one. Even Django Rest Framework had built in classes to be used for user authentication and that’s what you can find in the documentation, we knew we’d need to implement customised models and logic for client authentication.

So we started off with defining a custom APIClient model as follows:

So whenever a new APIClient object is created, it will automatically generate a key and a secret and add it as an attribute to the object.

So For example, we’ll create a new APIClient for our android app as follows:

and then we provide client.key and client.secret to our android development team as they will need then while requesting an access token for their app.

The idea behind is, that we provide different clients with credentials (key and secret) just like a user has a username and a password. Then just like user authentication they give us the key and the secret and on the backend we decide whether this APIClient should have access to our API’s or not.

If the key and secret exist, match, are valid and are not expired yet, we provide the client with an encrypted access_token which they have to include in the request headers to access the API resources.

In order to achieve the above we’d now start off with implementing an API resource that authenticate the given key and secret and provide the clients with an access token if their request is valid.

The above view will return a valid access token to the client if they provide valid credentials (key and secret) in their request data. Once they have an access token they can include it in the request headers to access the data through the API resources.

Now we will implement the logic that determines whether the given access_token in the request is valid or not and if we should give the request access to our data. To do so we will create a custom authentication class that extends Django rest framework’s base authentication class.

The above class now can be used with the API views where we want to implement the client authentication and in case the request contains a bad access_token we will return 401 Unauthorized response to the client.

The above implementation can only be used for requests that require just the client authentication. But there are a lot of views where we would want to authenticate both the client and the user. And as rest framework would pass the authentication if any one of the authentication passes, We’d need to implement another authentication that authenticates both the client and the user for such views.

For endpoints where we required both the client and the user authentication we’d simply use the above class in the authentication_classes property of the APIView and for public endpoints where we do not require user authentication we’d use ClientAuthentication class.

If you are using this document as a reference to your work, Please do note the following points:

  • This is just a basic authentication implementation on the ORM end and you can additionally secure your data by implementing a security layer on the server end.
  • Make sure you use the above implementation with the SSL protocol i.e. over https as the communication over this protocol is encrypted and thus secure. Using such implementation over http is as good as having no authentication implementation’

If you have any questions or suggestion, Please do comment below.

Update:

Following is the requested utils package used in the examples below. Some of the code might have changed in the following package over time but this will give you a basic idea.

 

You Might Also Like

  • http://www.salian.in/ Pranab
    • geekunlimited

      That’s because it relies on python-social-auth, which will again on your client end (mobile app) just implements the user authentication, but not client authentication itself. This article is based on authenticating a client to make sure only allowed clients (not users) can use the api in case API endpoints are exposed.

  • punit dama

    “So For example, we’ll create a new APIClient for our android app as follows:

    client = APIClient.objects.create(name=’Android 5.2′)

    and then we provide client.key and client.secret to our android development team as they will need then while requesting an access token for their app.”

    How do you expect your client secret to be secure on your mobile app? I see that as clear security vulnerability because that would be used further to request access token…

    • geekunlimited

      There are different implementations on your mobile platforms to secure such data that has to be embedded in the client side code. For Example:

      1. You can use pro-guard for android to secure your keys and secrets
      2. You can also try to obfuscate such values using a custom encryption/decryption algorithm
      3. You can also use something like http://www.saikoa.com/dexguard to obfuscate such values.

      All in all, it’s a separate issue to securing such values on the client side. If you are interested, we can do a separate article for the same.

  • Raja Sudhan

    Can you please update with the snippets in the utils package that you imported ??

    • geekunlimited

      Hi Raja, I have updated the article with the utils package you requested.

  • http://miaz.ca Mia

    Thanks for the article! Just wondering if there’s a urls.py + pattern that was omitted from the example? Not sure how to test the view to get the token in curl. Thanks :)

    • geekunlimited

      The code was actually written on the fly, while I was writing the article, So it did not have a urls.py but if you’d like to test it you can map the GetClientAccessToken view to any url in your urlconfig to test it. For e.g. url(r’^api/v1/access/client/’, views.GetClientAccessToken.as_view(), name=’get_access_token’) and then test the url /api/v1/access/client.

      • http://miaz.ca Mia

        Ahh okay, figured as much, but wasn’t sure since I’m used to django but not to django restframework ;)

  • India Info

    Hello,
    You have new feature to provide security to your django web application by Django mfa, Django-mfa is a simple package sponsored by MicroPyramid to add extra layer of security to your django
    web application. It gives web app a randomly changing password as an
    extra protection. Follow documentation and raise issues if you want
    further support, features.

    Read more about multifactor authentication: https://micropyramid.com/blog/securing-django-with-multi-factor-authentication-using-django-mfa/Get the code in our git repository, https://github.com/MicroPyramid/django-mfa
    For detail documentation visit http://django-mfa.readthedocs.io/en/latest/index.html