Implementing Google Login With JWT in Django for RESTful API Authentication
It’s become common now implementing RESTful API since server can communicate with various devices to communicate each other. Using 3rd party login is not the exception. Nowadays it’s pretty common the application support login by Google for authentication either from mobile device, PC and so on. The problem is how we authenticate access without hold any session value which is called as statelessness in RESTful API? This short article will introduce you on how to implement it easily. First of all I assume you understand and able to created a basic Django project.
I myself for this article create a Django project named rest-stateless followed by created a Django app named google, therefore my directory structure will be like this (feel free to use this approach or another approach if you like to do so to organize your working directory structure):
Now we need to install Django Rest Framework to implement RESTful API in our application
$ pip install djangorestframework
inside INSTALLED_APPS in stateless/settings.py add ‘rest_framework’ so will be like this
INSTALLED_APPS = [
'google', # your newly created app
'rest_framework', # add this
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
at terminal inside your root project directory, let’s run a migration
$ python manage.py migrate
Let’s create our first API view just to test things out:
google/views.py
class HelloView(APIView):
def get(self, request):
content = {'message': 'Hello, World!'}
return Response(content)
register a path in the urls.py:
stateless/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import path
from google import views
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', views.HelloView.as_view(), name='hello'),
]
now we can try to access http://localhost:8000/hello to see the result as follow:
Great, we just implemented the basic infrastructure for our RESTful API and now we’re going to implement jwt auth and using google token for authentication. Let’s install django-rest-framework-simplejwt
$ pip install djangorestframework_simplejwt
then install requests
$ pip install requests
add this code in settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
Let’s modify google/views.py become like this:
Finally in stateless/urls.py we modify as follow:
Cool, we have created a method to authenticate but how to test it? let’s go to https://developers.google.com/oauthplayground/ and we’re going to create a valid goole token to be tested in our application. At input your own scopes let’s add this:
https://www.googleapis.com/auth/userinfo.email
So maybe in the future you can grab email when made request. For further detail about scope you can visit this page
click Authorize APIs and Sign in using your own Google account followed by clicking Exchange authorization code for tokens. We got something like this:
now we can copy access token and test our application using curl as follow:
curl -X POST \
http://localhost:8888/google/ \
-H 'Content-Type: application/json' \
-d '{
"token": "__PASTE YOUR ACCESS TOKEN HERE__"
}'
Cool! We have implemented the token. Now depends on your needs you can keep using this token for authentication or create a new user then grant a new jwt access token.
For testing purpose we can try to implement authentication to localhost:8000/hello/ , let’s modify a bit by adding
#permission_classes = (IsAuthenticated,)
below “class HelloView(APIView):” so the code will be like this
class HelloView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request):
content = {'message': 'Hello, World!'}
return Response(content)
also don’t forget to import the library on top
from rest_framework.permissions import IsAuthenticated
last in settings.py we need to tell Django that we’re using jwt authentication
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
Now if you access localhost:8000/hello/ you’ll get error message
"detail": "Authentication credentials were not provided."
Therefore we need to make request using curl by also adding access token we create from /google endpoint, so the curl will be like this:
curl -X GET \
http://localhost:8888/hello/ \
-H 'Authorization: Bearer PUT_ACCESS_TOKEN_HERE'
If you executed this command you can see message “Hello World!” again. Congratulation we have accomplished authentication from google to our RESTful API in Django.