Calling REST API with JWT Authentication in Django

tina
7 min readNov 19, 2021
Walkiddie Register, Sign In and Reset Password Flow

Authentication is an essential part of a website. To authenticate means that providing a credential that can verify that you are a valid user of the system. Since I build my project’s backend in Django, I will be explaining how I implement sign-up, sign-in, reset password features in my application’s backend using a library called Djoser. The above video shows the final outcome by integrating Backend REST API with Django and Frontend with React. In this post, I will only be covering the A-Z implementation in the backend, which enables us to consume the API for our frontend site.

Understanding REST API and Django is required to proceed with reading the article.

The Django Rest Framework is a package for faster building REST APIs with Django. The Djoser provides basic views to handle authentication actions such as create user, login, logout. There are many ways to implement authentication in DRF (docs). The popular ones are:

  • Token-based Authentication (docs),
  • JSON Web Token (JWT) (docs).

What is the difference between them?

  • Token-based authentication requires database look up on every request to check if token is valid.
  • JWT is using cryptography to validate the token — no database queries.
  • Token-based authentication is using the same token for all sessions.
  • JWT is using different token for each session (even if the same user is logged from many devices).
  • Token-based tokens doesn’t have a timestamp for expiration time.
  • JWT tokens expire after selected time period and need to be refreshed.
  • For Token-based authentication, you can force user to logout by changing the token in the database.

In this post, I will use JWT authentication.

How JWT Works

Authentication using JWT (JSON Web Token) is very useful for developing cross-platform applications. The flow of the authentication process is :

  1. User logs in using their credentials. On successful login, the server issues an access token that is valid for a certain period of time (say 60 minutes).
  2. On every request to a protected resource, the token must be provided in the request as a header.
  3. When the token expires after the stipulated time (60 minutes in our case), the user gets logged out of the system and needs to log in again.

Simply put, JWT is a format that gives us back access and refresh token when logging in to a website — the two tokens that will allow us to access data on the website.

  • Access token: contains all the information the server needs to know if the user can access the resource you are requesting or not. They are usually expired with a short validity period.
  • Refresh token: The refresh token is used to generate a new access token.

How I Implemented Them in My Project

I’m using a Django backend and React frontend. They are placed in a different repo as an independent service. For now, I will only be covering the Django implementation. The flow that I planned is as follows:

There are three scenarios: 1) Register: After a user fills out a registration form and submits, she’ll receive a verification mail. In that mail, a URL to verify the account is provided. User clicks verify and will successfully be registered. The other two are self-explanatory.

Prerequisites: Django project and virtual env set up.

First, you need to install the following libraries:

  • djangorestframework
  • djoser
  • djangorestframework-simplejwt
pip install djangorestframework, djoser, djangorestframework-simplejwt

Second, create a new app.

 django-admin startapp accounts

Third, add the three highlighted new apps to your settings.

Fourth, since we want to store users first name, last name, email, and role, we are going to create a custom model.

  • Go to accounts/models.py (adjust to your site needs)

Fifth, to enable this, go back to settings.py and add the code below in the last line.

AUTH_USER_MODEL = ‘accounts.UserAccount’

Sixth, we’ll enable users to access the URLs by adding the two highlighted lines in project/urls.py.

Seventh, we’ll send automated emails to verify new users and confirm reset password requests. Add the following red-boxed code in settings.py. For security reasons, save EMAIL_HOST_USER (your Gmail address) and EMAIL_HOST_PASSWORD(your Gmail password) values in .env.

Eighth, create UserCreateSerilizer in accounts/serializers.py to translate Django objects to native Python format.

Lastly, in settings.py, add the following codes. Line 2–6 declares JWT for authentication. Line 8–15 sets the token’s type and lifetime. You can discard lines 16 — 17 for now, but you’ll need them when integrating with the front end. Line 18–32 sets the feature we want to apply on our site. These lines are basically telling Djoser to enable automated emails for new password confirmation and user activation, set the URLs attached in the mails, reset the unique field for login (by default is username), require password retype, and many more which you can discover at Djoser’s documentation.

Everything is set up! Now let’s test the API.

API Testing in Postman

All Djoser functionality are available at https://djoser.readthedocs.io/en/latest/settings.html

In every screenshot below, make sure you have set the Headers with:

1. Create User

(https://djoser.readthedocs.io/en/latest/base_endpoints.html#user-create)

After receiving ‘201 created’ response, you’ll receive an activation email. If not, check your Djoser specification in settings.py.

2. Verify User

Since we haven’t implemented the frontend, extract the sub url from the link stated in the email that structured /{uid}/{token}, and activate through API such follows:

When successful, you’ll receive a confirmation email.

3. Login

Now let’s log in with our credentials by posting to /auth/jwt/create. Remember that /auth is the location that we have specified earlier in urls.py, so the endpoint that purely comes from JWT is the /jwt/create.

You’ll receive an access token that will be used for accessing the website features and your own data.

4. Accessing Other Endpoints with Access Token

To see that in action, go to any other endpoints ( mine is the endpoint to get Pengadaan sales ) and copy your access token in Authorization as follows. Now you are authorized to access that endpoint and you’ll obtain the data that you won't get without passing the token!

5. Refreshing Token

We have set the access token lifetime to 60 minutes in settings.py. When it ends, you can post the refresh token and get a new access token to keep you signed in.

6. Forgot Password

To request a new password, post your email address to the following endpoint.

7. Reset Password

To reset password, extract the uid and token from the above email. Post them along with new_password and re_new_password to /auth/users/reset_password_confirm/.

My Thoughts

In such client-server architecture where the API is consumed by the frontend, building APIs without many abstractions is very helpful. Djoser helps us to do so. We don’t need to create a register, sign in, or reset password CRUD functions in views.py, instead just add a few lines of codes in settings.py and your API will be ready to use. Not only these three functionalities, there are many more which you can discover at Djoser documentation. This way, it will be easier to maintain our code and debug errors. Cheers!

Source

--

--