Manually creating and logging into accounts on the internet can be time-consuming. Social authentication, a mechanism for users to sign in (and sign up) with an application using login information from a social network provider with which they already have an account, solves this problem in modern web applications.
Social authentication entails the creation of workflows (also called apps) on third-party sites (e.g., Facebook, GitHub, Google, Twitter) that allow users to re-use their identity to access external resources (in our instance, Django applications). This functionality is helpful in Django apps because it allows users to register with just a few clicks rather than a lengthy registration procedure.
At their most basic level, social authentication systems include users authorizing tokens, which are subsequently exchanged between third-party sites and the requesting party (your Django application) to display a user’s authorization.
In addition, depending on the application and its setup, the requesting party (i.e., the Django application) can request basic user information (e.g., email) as well as more detailed information (e.g., a user’s Facebook friends) from the third-party site.
Django Authentication with Google
This article will create a Django application that allows users to sign in using their Google account.
Creating Django Application
We will create a new Django application from scratch for this application. Below are the steps to follow.
1) mkdir dev && cd dev
2) virtualenv google_env
3) source google_env/bin/activate
3) pip install Django==3.2.6
4) Create a new Django project (django-admin startproject DjangoGoogleLogin)
5) Navigate to the newly created project(cd DjangoGoogleLogin)
6) Start a new Django app (python manage.py startapp google_login)
7) python manage.py migrate
8) python manage.py runserver
Upon successful running, you should be able to navigate to http://127.0.0.1:8000, where you will view an instance of your Django application as follows.
Project Configuration
First, we will add our newly created app in the INSTALLED_APPS under the settings.py. It is a standard procedure to install your newly created app in your project. You do this in your settings.py under the section INSTALLED_APPS as shown below.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'google_login', ]
By adding this new line of code, your project knows the existence of our newly created app.
Specify the path of the template under TEMPLATES
In the settings.py, locate TEMPLATES, then make the following modifications
{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates/'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
Add both the media and static folders in STATIC_ROOT
In your settings.py, add the following set of lines.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Update urls.py
At this point, you can update urls.py with your desired URL for the newly created app
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('allauth.urls')), path('', include('google_login.urls')), ]
Create a new urls.py for the newly created app
Now, we need to create a urls.py in the google_login app as follows:
# google_login/urls.py from django.urls import path from .views import view_name urlpatterns = [ path('', view_name, name="view_name"), ]
The urls.py module helps us to include our URL configuration for our newly created app. In addition, we need to hook up the URLs to enable us to visit the page we completed recently.
What happens is that any URLs defined in urls.py are registered when you visit the URL’s root path, which is localhost:8000.
Make APP Setting Configurations
create new templates under google_login/templates/
We will require an HTML template that will interact with the view function to display information to the user.
first, create a templates directory under the new app
mkdir google_login/templates/
Then, create a templates file called home.html
touch google_login/templates/home.html
Create a View function
In our google_login app, let’s create a view function in views.py. Recall that views are classes or a collection of functions in views.py found in our app directory.
Each function or class deals with a specific logic and is usually processed when the said URL is visited.
from django.shortcuts import render def view_name(request): return render(request, 'home.html', {})
Django-allauth
What is the purpose of Django-allauth?
Django-allauth is an authentication module for Django. It handles authentication, registration, account management, and 3rd party (social) account authentication – an integrated set of Django apps. It comes with a fully integrated authentication software that supports both local and social authentication and simple flows.
how to install Django-allauth
Run the following command to install Django-allauth
pip3 install django-allauth
How to configure Django-allauth
Django-allauth settings.py is used to configure Django-allauth.
After installing the package, add django-allauth to INSTALLED_APPS in settings.py to register it. Essentially, you can include any of the providers you need to register. The updated INSTALLED_APPS should appear as follows:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', # Add this # Add the following django-allauth apps 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.google', # ... ]
Also, add the following allauth configuration settings and backend settings at the bottom of the settings.py.
AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend' ]
In addition, you also need to add the SITE_ID and also specify the redirect URL. The latter will be helpful when the user logs in successfully. Other configuration settings can also be added as below.
SITE_ID = 1 LOGIN_REDIRECT_URL = '/'
Additional configuration settings
SOCIALACCOUNT_QUERY_EMAIL = True ACCOUNT_LOGOUT_ON_GET= True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_EMAIL_REQUIRED = True
Further, users’ email addresses can be received upon a successful login if the email scope is enabled. It can be done with the following configurations.
SOCIALACCOUNT_PROVIDERS = { 'google': { 'SCOPE': [ 'profile', 'email', ], 'AUTH_PARAMS': { 'access_type': 'online', } } }
urls.py
Add the allauth urls to the urls.py file in your project directory and import include at the top. We create the /accounts route, which contains all Django-allauth URLs. This route will be used for all OAuth activities.
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('allauth.urls')), path('', include('google_login.urls')), ]
Creating a SuperUser in Django
We will create a superuser for our Django application by running the following command on the terminal.
$ python manage.py createsuperuser
Subsequently, we will fill in the required details that comprise the username, the email address, and both a password and a confirmation of the same.
Setting up Google APIs
First, we will need to set up an OAuth application in Google Developers Console to add Google login to our app.
The starting point is creating a new Google APIs project in the Google Developer APIs Console. To accomplish this, we will access the dashboard so that we can create the new project.
We will give our new project a name, preferably the name of our website or app. When we send users to the Google login page, they will see this project name. In our case, we will name it, DjangoGoogleLogin. Then, we will proceed by clicking on ‘Create.’
NOTE: All we need is a Google APIs project and a complete Client ID and Client Secret.
Go to the OAuth Consent Screen and register your app
Fill out the OAuth consent screen to register your app. Under ‘Developer contact information,’ you need to submit ‘App name,’ ‘User support email,’ and ‘Email addresses.’ To save and continue, click the ‘Save and Continue button’.
Creating new API Credentials
We will click on the ‘Create Credentials’ button under Credentials at the very top section on the dashboard. Subsequently, we will select the option ‘OAuth Client ID’ alternative.
We will then provide the following URIs under the section ‘Authorized Javascript origins’:
http://localhost:8000 http://127.0.0.1:8000
Then, we will add the following URIs under ‘Authorized redirect URIs’:
http://127.0.0.1:8000/accounts/google/login/callback/ http://localhost:8000/accounts/google/login/callback/
The above URIs are almost similar because the Django application is accessible through 127.0.0.1:8000 or localhost:8000. Only remember to update the URIs to the given domain name once the app is in production.
Now, note down the Client ID and the Client Secret. Those can be found on the left-hand side of the page.
Adding Google OAuth 2 Credentials to Django App
First, we will run the application by using the following command.
python manage.py runserver
We can now access the site using any of the following links, http://127.0.0.1:8000/admin or http://localhost:8000/admin. The latter will enable us to access the Django admin page for our DjangoGoogleLogin app.
We will fill in the necessary details that comprise a Domain name and a Display name under the section sites. For each, we will populate with localhost:8000 and 127.0.0.1:8000.
These are not fixed either. You could have a different site for your application, for instance, ‘example.com,’ or by using whatever appealing name that resonates with you. Just remember to add this under the sites, as shown in the image below.
Next, we will populate the following fields under the social applications. To enable this, you need to click add. You will need to fill the following:
- provider: Google
- Name
- Client ID
- Secret Key
- In the available sites, choose your sites and use the right-facing arrow to move it to the section named ‘Chosen sites.’
Remember that we are currently logged in as the system admin. So, we will need to log out to attempt to authenticate using our Google account.
More often than not, you will get the following error: ‘SocialApp matching query does not exist at http://127.0.0.1:8000/accounts/google/login/. That implies that the site ID created in the Django admin is not like the one in settings.py.
Also, it could be because an ‘example.com’ site is already created for you by Django, especially when the project is not new. The solution to this is to delete the later entry from the Sites admin page. Then, make changes to the SITE_ID in settings.py to the expected ID. On the other hand, you could also play with the value of SITE_ID, like setting it to 4 or 3.
Testing Authentication with your Google Authentication
The template for this purpose will consist of the following details:
{% load socialaccount %} <html> <head> <title>Google Registration</title> </head> <body> <h1>My Google Login Project</h1> {% if user.is_authenticated %} <p>Welcome, {{ user.username }} !</p> {% else %} <h1>My Google Login Project</h1> <a href="{% provider_login_url 'google' %}">Login with Google</a> {% endif %} </body> </html>
Access the home page at the link, http://127.0.01:8000/. Here, there will be a button prompting you to sign in with the Google login, which should redirect you to the Google login page to log in or authorize the app in case you are already logged in to your Google account.
When the Authentication is successful, you should be in a position to see the following welcome screen with your name mentioned – of course, that is the name registered on your Google account. In our case the name is masa.
Information on the logged-in User
You can check the user information collected from Google at http://127.0.0.1:8000/admin/socialaccount/socialaccount/ after signing in with Google.
Google doesn’t provide much information about its users. Your app must be verified to receive more user data from Google.
For individuals that signed up with their social account, a SocialAccount model instance is offered.
Simply write the following in your template:
Avatar URL: {{ user.socialaccount_set.all.0.get_avatar_url }} UID: {{ user.socialaccount_set.all.0.uid }} Date Joined: {{ user.socialaccount_set.all.0.date_joined}} Last Login: {{ user.socialaccount_set.all.0.last_login}} Full Name: {{ user.socialaccount_set.all.0.extra_data.name }}
Here is the complete code for most sections to help you follow through easily:
# settings.py """ Django settings for DjangoGoogleLogin project. Generated by 'django-admin startproject' using Django 3.2.6. For more information on this file, see https://docs.djangoproject.com/en/3.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/3.2/ref/settings/ """ from pathlib import Path import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-w27&t$h@(d6cvpby!2#u-26y8r7%ex0_w&v*5_=b7g5+=09ex=' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'google_login', 'django.contrib.sites', # Add this # Add the following django-allauth apps 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.google', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'DjangoGoogleLogin.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates/'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'DjangoGoogleLogin.wsgi.application' # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } # Password validation # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ STATIC_URL = '/static/' # Default primary key field type # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_ROOT = os.path.join(BASE_DIR, 'media') AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend' ] SITE_ID = 3 LOGIN_REDIRECT_URL = '/' # Additional configuration settings SOCIALACCOUNT_QUERY_EMAIL = True ACCOUNT_LOGOUT_ON_GET= True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_EMAIL_REQUIRED = True SOCIALACCOUNT_PROVIDERS = { 'google': { 'SCOPE': [ 'profile', 'email', ], 'AUTH_PARAMS': { 'access_type': 'online', } } }
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('allauth.urls')), path('', include('google_login.urls')), ]
# views.py from django.shortcuts import render def view_name(request): return render(request, 'home.html', {})
Conclusion
Overall, we’ve been successful in using Google to authenticate users in our Django application. While this guide only looks at Google’s OAuth 2.0 authentication, you may use Django-allauth to incorporate other OAuth providers as well.
We hope that you will be able to use it in your future projects.