Change language

Python Django | Google authentication and mail retrieval from scratch

Now let’s create a Django 2.0 project, then implement Google Authentication Services and then fetch mail. We’re only doing mail extraction to show you how to request permission after authentication.

Step # 1: Create the Django project

The first step is to create a virtual environment and then install the dependencies. So, we’ll use venv :

 mkdir google-login & amp; & amp; cd google-login python3.5 -m venv myvenv source myvenv / bin / activate 

This command will create one folder myvenv through which we just activated the virtual environment. Now type

 pip freeze 

Then you shouldn’t see any dependencies installed in it. Now, first thing we do is install Django:

 pip install Django == 2.0.7 

This is the version of Django we used, but feel free to use any other version. Now the next step is — create one project, gfglogin its gfglogin :

 django-admin startproject gfglogin. 

Since we are in the google-login directory so we want the django project to be in this directory just for you to use. " & # 39; at the end to indicate the current directory. Then create one app to separate the logic from the main project, so create one app named gfgauth :

 django-admin startapp gfgauth 

So the general the terminal will look like this:

Since we have created one application. Add this application name to in the INSTALLED_APP list. We now have a Django project running, so let’s move it first and then check if there are any errors or not.

 python makemigrations python migrate python runserver 

So after migration you need to be able to start the server and see the Django start page at that particular URL.

Step # 2: Install dependencies

Since the project has started successfully, let’s set the basic requirements. First, we need googleapiclient , this is necessary because we need to create one resource object that helps to interact with the API. Therefore, to be precise, we will use the ’build’ method from it.


 pip install google-api-python-client == 1.6.4 

Now the second module is oauth2client , it will oauth2client all authentications, credentials, streams and more, so it’s important to use that.

 pip install oauth2client == 4.1.2 

Finally, install jsonpickle (just in case it is not installed) because it will be used oauth2client when creating a CredentalsField .

 pip install jsonpickle == 0.9.6 

So these are the only dependencies we need. Now let’s move on to a piece of code and see how it works.

Step # 3: Create Models

Use Models to store the credentials we get from the API, so there are only two main fields to take care of. The first — this is the id , which will be the ForeignKey, and the second — credential equal to CredentialsField. This field needs to be imported from oauth2client. So our will look like this:

from django. contrib import admin

from django.contrib.auth.models import User

from django.db import models

from oauth2client.contrib.django_util.models import CredentialsField



class CredentialsModel (models.Model):

id = models.ForeignKey (User, primary_key = True , on_delete = models.CASCADE)

credential = CredentialsField ()

task = models.CharField (max_length = 80 , null = True )

updated_time = models.CharField (max_length = 80 , null = True )



class CredentialsAdmin (admin.ModelAdmin):

pass ,

Currently time task and updated_time are just additional fields, so you can remove them. Thus, these credentials will contain the credentials in the database.

Important note:

When we import the CredentialsField , the __init__ method is automatically executed and if you notice code in the path
/google-login/myvenv/lib/python3.5/site-packages/oauth2client/contrib/django_util/__init__. py Line 233

They import urlresolvers so they can use the reverse method from there. Now the problem is that this urlresolvers was removed after Django 1.10 or Django 1.11. If you are working with Django 2.0 it will give an error that urlresolvers cannot be found or is missing there.

Now, to overcome this problem, we need to change 2 lines, first replace the import from django. core import urlresolvers to from django.urls import reverse

And then replace urlresolvers.reverse (...) 411 urlresolvers.reverse (...) to reverse(...)

You should now be able to run it successfully.

After creating these models:

 python makemigrations python migrate 

Step # 4: Create views

At the moment we have only 3 main views for processing requests. First, we need to show the home page, status, google button so that we can send an authentication request. The second view will be launched when the google button is clicked, which means an AJAX request. Third, process the refund request from Google so that we can accept the access_token from it and store it in our database.

First, let’s do Google Authentication:

So, right now we need to tell the stream to the API what permissions we need to ask, what is my secret key and redirect url. To do this, enter:

 FLOW = flow_from_clientsecrets (settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON, scope = ’ / auth / gmail.readonly’, redirect_uri =’ 8000 / oauth2callback’, prompt = ’consent’) 

As you can see settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON , go to and type:

 GOOGLE_OAUTH2_CLIENT_SECRETS_JSON = ’client_secrets.json’ 

This tells Django where the json file is located. We’ll download this file later. After defining the flow, let’s start the logic.

Whenever we need to find out if someone is authorized or not, we first check our database to see if these user credentials already exist or not. If not, then we make a request to the API URL and then get the credentials.

def gmail_authenticate (request):

storage = DjangoORMStorage (CredentialsModel, ’id’ , request.user, ’credential’ )

  credential = storage.get ()


if credential is None or credential.invalid:

  FLOW.params [ ’ state’ ] = xsrfutil.generate_token (settings.SECRET_KEY,

request .user)

authorize_url = FLOW.step1_get_authorize_url ()

return HttpResponseRedirect (authorize_url)

else :

http = httplib2.Http ()

  http = credential.authorize (http )

service = build ( ’gmail’ , ’v1’ , http = http)

print ( ’ access_token = ’ , credential.access_token)

  status = True


  return render ( requ est, ’index.html’ , { ’ status’ : status})

We use DjangoORMStorage (which is provided by oauth2client ) so that we can store and retrieve credentials from Django datastore So we need to pass 4 parameters for this. The first is the model class, which has a CredientialsField. The second — it is a unique identifier having credentials meaning the name of the key, the third — it is the key that has credentials, and the last — the name of the CredentialsField that we specified in .

Then we get the value from the store and see if it is valid or not. If not valid, we create one user token and get one authorization URL, where we redirect the user to the google login page. After being redirected, the user fills out the form, and once the user is logged in with Google, Google will submit the data to the callback URL with access_token which we will do later. Now in case the user credentials were already present then it will re-validate the credentials and return you an access_token or sometimes an updated access_token in case the previous one expired.

Now we need to handle the callback url to do this:

def auth_return (request):

get_state = bytes (request. GET.get ( ’state’ ), ’ utf8’ )

if not xsrfutil.validate_token (settings.SECRET_KEY, get_state,


  return HttpResponseBadRequest ()


credential = FLOW.step2_exchange ( request.GET.get ( ’code’ ))

storage = DjangoORMStorage (CredentialsModel, ’id’ , request.user, ’ credential’ )

storage.put (credential)


print ( " access_token:% s " % credential.access_token)

return HttpResponseRedirect ( "/" )

Now inside the callback url when we get one response from Google, then we collect the data and get the state from it , condition — it is nothing more than a token that we generated with generateToken. Therefore, we verify the token using the secret_key, the token we generated, and the user who generated it. These things are checked by the xsrfutil.validate_token method which checks that the token is not too old over time and was only generated at a specific time. If these things don’t work then it will give you an error, otherwise you will go to the next step and share the code from the callback response with Google so you can get the access_token.

So it was a two-step check. and after successfully getting the credentials, we store them in the Django datastore using DjangoORMStorage, because with that only we can get and store the credentials in the CredentialsField. Once we save it, we can redirect the user to any specific page, and this is how you can get the access_token.

Now let’s create one home page that tells if the user is logged in or not.

def home (request):

  status = True


if not request.user.is_authenticated:

  return HttpResponseRedirect ( ’admin’ )


storage = DjangoORMStorage (CredentialsModel, ’ id’ , request.user , ’credential’ )

  credential = storage.get ()


try :

access_token = credential.access_token

  resp, cont = Http (). request ( " .readonly " ,

  headers = { ’ Host’ : ’’ ,

’Authorization’ : access_token})

except :

status = False

print ( ’ Not Found’ )


  return render (request, ’index.html’ , { ’status’ : status})

Right now we assume the user is authenticated in Django, which means the user is no longer anonymous and the information is stored in a database. Now, to support anonymous user, we can remove credential checks in the database or create one temporary user.

Back to the original view, we first check if the user is authenticated or not, which means the user is not anonymous if yes then force it to login, otherwise check credentials first. If the user is already logged in with Google, it will display the status as True, otherwise it will display as False.

Now on to the templates, let’s create one. First go to the root folder and create one folder named & # 39; templates & # 39; and then inside index.html create index.html :

{% load static%}
& lt;! DOCTYPE html"

" html lang = "en" "


" head "

" meta charset = "UTF-8" "

" script src = " {% static ’js / main. js’%} " " "/ script "

" title " Google Login "/ title "

"/ head "

" body "


" div "

" div "

{% if not status%}

" a href = "/ gmailAuthenticate" onclick = " gmailAuthenticate () " title = "Google" " Google "/ a "

{% else%}

" p " Your are verified "/ p "

{% endif%}

"/ div "


"/ div "

"/ body "

"/ html "

This page is now very much simplified so there is no CSS or styles, there is only one simple link to check. You will now also notice the js file . so go to root folder again and create one directory as static/js/

And inside js create one file javascript main.js :

function gmailAuthenticate () {

$. ajax ({

  type: " GET " ,

url: "ajax / gmailAuthenticate" ,

// data: & # 39; & # 39 ;,

success: function (data ) {

console.log ( ’Done’ )




This js file was used to separate the logic from the HTML file, and also to make a single AJAX call to Django. We now have all the parts made for viewing.

Step # 5: Create URLs and Basic Settings

In the main gfglogin project / means gfglogin / edit and put:

from django.contrib import admin

from django.urls import path, include


urlpatterns = [

path ( ’admin /’ ,,

  path (’ ’, include (’ gfgauth.urls ’)),


Because we need to test the functionality of the gfgauth application. Now inside gfgauth / enter:

from django.conf .urls import url

from . import views


urlpatterns = [

url (r ’^ gmailAuthenticate’ , views.gmail_authenticate, name = ’gmail_authenticate’ ),

url (r ’^ oauth2callback’ , views.auth_return),

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              url (r ’^ $’ , views.home, name = ’home’ ),


How see, gmailAuthenticate is for AJAX calls, oauth2callback — for the callback url and the last — for the homepage url. Now, before launching, there are several settings that we did not talk about:

In you need to edit:

  1. To the "TEMPLATES" list add "templates" to the "DIRS" list.
  2. Finally from the file add:
     STATIC_URL = ’/ static /’ STATICFILES_DIRS = ( os.path.join ( (BASE_DIR, ’static’) ,) GOOGLE_OAUTH2_CLIENT_SECRETS_JSON = ’client_secrets.json’ 

So we just pointed out where templates and static files are present and, most importantly, where the google secret json file is located oauth2 client. We will now download this file.

Step # 6: Generate the Oauth2 client secret file

Go to google developer console page, create one project and name it whatever you like. Once created, go to the project dashboard and click on the navigation menu that is on the top left. Then click on API services and then on the credentials page. Click on create credentials (you may need to set the product name before going ahead, so do that first). Now select the web app since we are using Django. After that, provide a name, and then just go to redirect the URI, and in there type: 

And then save that. You do not need to specify the source of the authorized Javascript, so leave this blank. After saving you will be able to see all your credentials, just load them, they will be saved under some random names, so just reformat the filename and enter "client_secrets" and make sure it is in json format. Then save it and paste i


Gifts for programmers

Learn programming in R: courses

Gifts for programmers

Best Python online courses for 2022

Gifts for programmers

Best laptop for Fortnite

Gifts for programmers

Best laptop for Excel

Gifts for programmers

Best laptop for Solidworks

Gifts for programmers

Best laptop for Roblox

Gifts for programmers

Best computer for crypto mining

Gifts for programmers

Best laptop for Sims 4


Latest questions


Common xlabel/ylabel for matplotlib subplots

1947 answers


Check if one list is a subset of another in Python

1173 answers


How to specify multiple return types using type-hints

1002 answers


Printing words vertically in Python

909 answers


Python Extract words from a given string

798 answers


Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

606 answers


Python os.path.join () method

384 answers


Flake8: Ignore specific warning for entire file

360 answers



Python | How to copy data from one Excel sheet to another

Common xlabel/ylabel for matplotlib subplots

Check if one list is a subset of another in Python

How to specify multiple return types using type-hints

Printing words vertically in Python

Python Extract words from a given string

Cyclic redundancy check in Python

Finding mean, median, mode in Python without libraries

Python add suffix / add prefix to strings in a list

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

Python - Move item to the end of the list

Python - Print list vertically