Types of API Authentication In Django REST Framework
Tags: python, django, security, webdev
Published: 2020-04-11 12:15:14

# Introduction
When I first started to dive deeper into building RESTful APIs using the Django Rest Framework. I was given a task to create authentication for the front-end. So that they will be able to identify themselves for specific roles that allow them specific access toward features or data that is associated with their user account. 

With 3 account types  **visitor**, **existing user** and **administrator** The `administrator` has full control of managing the user account from updating of any user account details to password recovery. Due to Django's built-in approach, account management for multi-tenancy is relevantly easy. Whereas authentication of a user from API requests is a different ball game entirely ranging from easy to advance based upon your needs. 

# Basic Authentication
The most basic form of authentication is through the use of the Django `user` instance. Which falls under the`user` models that were created for your user. Provided the user account was assigned with the right [permission][1] to access specific APIs or data within the system. 

User authentication requires that the API request contain both `username` & `password`. Which is checked under `django.contrib.auth.User` instance this returns 3 types of `status code` namely:

* 200 (Ok) - User is authenticated with the right permission to access the API.
* 401 (Unauthorized)- Error that occurs when an invalid username and password is given for the API request.
* 403 (Permission Denied)- A default error for DRF that occurs when the user does not have the right permission to access the API despite the user is authenticated.

```python
# API methods
@api_view(['GET'])
# Types of authentications
@authentication_classes([SessionAuthentication, BasicAuthentication]) 
# Checks for the user's permission if they are allowed access to this view
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
    content = {
        'user': unicode(request.user),  # `django.contrib.auth.User` instance.
        'auth': unicode(request.auth),  # None
    }
    return Response(content)

```

It is important to note that for the above code from the DRF documentation should be used for **testing** purposes only. If you insist on using it for production. It must be transmitted through `HTTPS` to prevent hackers from [sniffing][2]. With the `username` & `password` a hacker can conduct a [Man in The Middle Attack][3] to gain access in a production environment. 

# Token-Based Authentication
The use of token-based authentication is an upgrade for authentication. It requires you to generate and store an authentication token within both the user model in the database and your front-end has to save it for it to work.

For API request, instead of both the `username` & `password` to authenticate the user. You just provide the `authentication token` to authenticate the user. This authentication token can be generated by you through an independent API that focuses on it. The other way is that you add the token generation part into your login API to return a response with the authentication token. Whenever the front-end calls the `login` API and provides the correct user credentials.

# 3rd Party Packages
If you had come so far, I believe one of the things that might come to you is that the default Django REST Framework does not fit my use case for it. This might take lots of time to create each API. You would like to reduce time and effort or customise it further. Perhaps you are looking to integrate JWT, OAuth or some other form of authentication that is not provided by default from Django REST Framework. 

How would I proceed to do it? Well here's my recommendation for Django packages for your authentication that might fit the use case that you might have in mind:
* [SimpleJWT][4] - Ease of generating and authentication a JWT that includes a feature for blacklisting.
*  [Django REST Knox][5] - A security focus Django package that has a feature for tokens with an expiry of up to 10 hours and tokens is encrypted in the database.
* [Dj-Rest-Auth][6] - Handles all of your authentications needs without much coding from registration, password recovery to social media authentications and it even includes the use of JWT as well.

# Conclusion
When it comes to authentication for API in Django REST Framework. There is not really a one size fit all approach. Instead, it comes with its own trade-off in implementation, layered security approach, scale, speed and resources allocated to allow the development of API to provide the correct access to the right users.

Do note regardless of the type of authentication method you use, you must use `HTTPS` in a production environment for data privacy and security reasons. I would suggest you look at the [OWASP Top 10 APi][7] as a form of reference when developing API while considering the security aspect of it.

If you like this article do **sign up** for my [Adventurer's Newsletter][8] which contains interesting content I stumble across over the week in the area of **Python**, **Web Development**, **Startup**.

You can also **follow** me to get the **latest** update of my article on **Dev**

The original post was on [Types of API Authentication In Django Rest Framework - Reading Time: 4 Mins][9] and cover image by [John Salvino on Unsplash][10]

# Reference
* [Permissions][1]
* [JSON Web Token (JWT)][11]
* [OAuth][12]
* [Network Sniffer][2]
* [Man in The Middle Attack][3]
* [Django REST Framework API Guide On Authentication][13]
* [Why JWT Suck as Sessions Tokens][14]
* [Dj-Rest-Auth][6]
* [SimpleJWT][4]
* [Django REST Knox][5]
* [OWASP Top 10 API Security in 2019][7]


[1]: https://www.django-rest-framework.org/api-guide/permissions/
[2]: https://www.lifewire.com/definition-of-sniffer-817996
[3]: https://www.veracode.com/security/man-middle-attack
[4]: https://github.com/SimpleJWT/django-rest-framework-simplejwt
[5]: https://github.com/James1345/django-rest-knox
[6]: https://github.com/jazzband/dj-rest-auth/
[7]: https://owasp.org/www-project-api-security/
[8]: https://maxongzb.activehosted.com/f/1
[9]: https://www.maxongzb.com/types-of-api-authentication-in-django-rest-framework-reading-time-4-mins
[10]: https://unsplash.com/photos/bqGBbLq_yfc
[11]: https://jwt.io/
[12]: https://oauth.net/
[13]: https://www.django-rest-framework.org/api-guide/authentication/
[14]: https://developer.okta.com/blog/2017/08/17/why-jwts-suck-as-session-tokens