The complete django-allauth guide
Tags: python, django, webdev, beginners
Published: 2019-07-17 05:57:26

---
title: The complete django-allauth guide
published: true
description: From Zero to Hero guide for django's most popular authentication library.
tags: Python, django, webdev, beginners
cover_image : https://miro.medium.com/max/1280/1*t5CFOq45fU1qCmdgIksLnQ.jpeg
---

User registration and authentication is one of the most essential components of a web application. This tutorial deals with setup, configuration, and customization of django-allauth along with advanced tweaks and social login setup for your django web app. This tutorial intends to serve as a guide for new users who want to get started quickly with django-allauth and make useful customizations along the way without much pain.

## Why this guide?

`django-allauth` is a very well written library thanks to [Raymond Penners](https://github.com/pennersr). However, it can be overwhelming to a `django` novice or advanced users using `django-allauth`for the first time. Although it is well documented, due to time and resource constraints of the developers involved, there has not been many articles and in-depth tutorials on the library. So this tutorial tries to solve that problem by making a comprehensive guide to get started quickly and also learn about advanced customization.

## Basic Setup

You can [download](https://github.com/gajeshbhat/django-experiments/tree/master/allauthdemo) the files used in the tutorial to get a head start. The steps below guide you through the setup in detail.

1. Create a Django project if you already don’t have one.

2. Install `django-allauth` using the command `pip install django-allauth`

Add,`allauthallauth.account`, `allauth.socialaccount` and all the social login features you need to `INSTALLED_APPS` section in `settings.py`. 

You can view the entire list of supported API's [here](http://django-allauth.readthedocs.io/en/latest/installation.html). 

The social login feature is described later in the post. You can scroll down to that subheading if you would like to just read that. After you configure your installed apps section, it should be similar to the code given below.

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.google',
    'allauth.socialaccount.providers.facebook',
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```
Configure the `template` context processor settings in `settings.py` and also add the url pattern in the project’s `urls.py`.

```
TEMPLATES = [
  {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.normpath(os.path.join(BASE_DIR, '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',
                'django.template.context_processors.request',
            ],
        },
    },
]
```
Add the following authentication backend.

```
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
)
```
Copy the template files from the `django-allauth` repository or you can also use my [custom repository](https://github.com/gajeshbhat/django-experiments/tree/master/allauthdemo/templates)(I have made some modifications and some good structuring) and paste it in the folder `templates` in your project directory.

Add the allauth urls in `urls.py` of your main project directory. After adding the allauth urls the urls file should look similar to,

```
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^accounts/', include('allauth.urls')),
]
```
You can also add the custom CSS yourself or my CSS (Well commented and documented but simple) that I have created during my use of the allauth templates. It includes styling for almost all the pages, and even mobile-friendly email templates for confirmation and password reset emails. You can do that by creating a `static` folder in the project directory and placing the CSS in the folder `accounts`.

Run `python manage.py makemigrations` and `python manage.py migrate` to make all the necessary migrations and run `python manage.py runserver` to start the django server.

Follow the URL patterns to display the registration form.
**Eg**: Visit `localhost:8000/accounts/login` to display the login page.

## Basic Configuration

Most `django-allauth` features are can be configured using the built-in adapters and variables by placing them in the file `settings.py`. Although the [documentation](http://django-allauth.readthedocs.io/en/latest/configuration.html) has tons of such options with good explanations, I have highlighted some important ones below.

**Email confirmation expiry**: Sets the number of days within which an account should be activated. 

**Eg**: `ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS=7`

**Email required for activation**: This option allows you to set whether the email address should be verified to register. Set False to disable email requirement. 

**Eg**: `ACCOUNT_EMAIL_REQUIRED = True`

**Account email verification**: This option can be used to set whether an email verification is necessary for a user to log in after he registers an account. You can use ‘mandatory’ to block a user from logging in until the email gets verified. You can set options for sending the email but allowing the user to log in without an email. You can also set none to send no verification email. (Not Recommended) 

**Eg**: `ACCOUNT_EMAIL_VERIFICATION = "mandatory"`

**Login Attempt Limit**: This is an important feature which can be used to prevent brute force attacks on the user login page on your website. The maximum number of login attempts can be set, and the user gets blocked from logging back in until a timeout. This feature makes use of `ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT` setting.

**Eg**: `ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5`

**Login Attempt Limit timeout**: This setting should be used with setting `ACCOUNT_LOGIN_ATTEMPTS_LIMIT`. The value set is in seconds from the last unsuccessful login attempt. Please note that this does not protect admin login. 

**Eg**: `ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT` = 86400 # 1 day in seconds

**Login and Logout URL redirection**: When user logs in or logs out, you might want to redirect the user to a particular URL or page and the below settings can be used to set that URL. By default, allauth redirects login to `/accounts/profile/` URL and logout to the localhost:8000 or any localhost homepage.

**Eg**: `ACCOUNT_LOGOUT_REDIRECT_URL ='/accounts/login/'` 
**Eg**: `LOGIN_REDIRECT_URL = '/accounts/email/'`

When you are done, your allauth settings should look similar to the below settings.

```
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS =1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 86400 # 1 day in seconds
ACCOUNT_LOGOUT_REDIRECT_URL ='/accounts/login/'
LOGIN_REDIRECT_URL = '/accounts/email/' # default to /accounts/profile 
```

## Extending the django-alluth class and advanced customizations

This section deals with customizing django-allauth signup forms, intervening in registration flow to add custom process and validations of your own. 

One of the most common queries about allauth is about adding additional fields or custom fields to the signup form. You can extend the `SignupForm` class from `allauth.account.forms`. All you need to do is create a custom class pass the `SignupForm` to the custom class and define the custom fields and save it. It's vital to return the user object as it will be passed to other modules for validations. You also need to include variables `ACCOUNT_FORMS` in `settings.py`.

Let us see this using an example. In `forms.py`.

```
from allauth.account.forms import SignupForm
from django import forms

class CustomSignupForm(SignupForm):
    first_name = forms.CharField(max_length=30, label='First Name')
    last_name = forms.CharField(max_length=30, label='Last Name')
    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
        return user
```
In the above snippet `CustomSignupForm` is an extended class which inherits all the features of `SignupForm` class and adds the necessary features. Here custom fields by the name `first_name` and `last_name` are created and saved in using the signup module in the same class.

The `ACCOUNT_FORMS` in `settings.py` for the above code is

```
ACCOUNT_FORMS = {
'signup': 'YourProject.forms.CustomSignupForm',
}
```
Any other custom forms created can be extended in `ACCOUNT_FORMS`. The list is illustrated in the [documentation](http://django-allauth.readthedocs.io/en/latest/forms.html#account-forms).

Similarly, `LoginForm` `UserForm` `AddEmailForm` and others can be extended. However, remember that when you extend these forms and link them in `settings.py`. Do Not forget to pass the original form (For example `SignupForm`) as a parameter to your class and sometimes you might have to handle custom validations and return user or some other value. Please refer to the [source code](https://github.com/pennersr/django-allauth/blob/master/allauth/account/forms.py#L362) to follow the correct flow.

### User Intervention and Custom validations

I recently encountered some good questions on stack overflow and on the repository issue section with regards to adding custom validations and intervening in the user registration flow. When researching for a solution and scanning through the documentation, I found the `DefaultAccountAdapter` very useful and indeed can be used to solve most of the customization problems that a user might encounter while using `django-allauth`. I reproduce the answers and with some instructions below.

### Example 1: Allow restricted list of email’s

After figuring out a way to store and fetch the restricted list, you can use the adapters and raise validation error in the registration form when a restricted email tries to register. Extend a `DefaultAccountAdapter` and override the `clean_email` method. Create an `adapter.py` in your project directory and extend the default adapter class. You can also restrict the email providers (such as temporary email providers) from registering using Regular expressions. I will not cover identifying the email prover (`user@provider.com`) as it is out of the scope of this article. But the flow remains the same.

```
from allauth.account.adapter import DefaultAccountAdapter
from django.forms import ValidationError

class RestrictEmailAdapter(DefaultAccountAdapter):
    def clean_email(self,email):
        RestrictedList = ['Your restricted list goes here.']
        if email in RestrictedList
            raise ValidationError('You are restricted from registering. Please contact admin.')
        return email
```
Finally, point the account adapter in the `settings.py` file to your extended class. `ACCOUNT_ADAPTER = 'YourProject.adapter.RestrictEmailAdapter'`

### Example 2: Add a Maximum length to a username

As `ACCOUNT_USERNAME_MAX_LENGTH` does not exist in the allauth library, `DefaultAccountAdapter` can be used to achieve this feature without much pain. Extend the `DefaultAccountAdapter` class and overriding the `clean_username` method. **You need to also reference the `clean_username` once again after the custom validation to complete other inbuilt validations**.

**Note**: The Last sentence in the above paragraph is the key to work with `DefaultAccountAdapter`. You should never forget to reference the original module name for the module to complete other validations.

```
from allauth.account.adapter import DefaultAccountAdapter
from django.forms import ValidationError

class UsernameMaxAdapter(DefaultAccountAdapter):
    def clean_username(self, username):
        if len(username) > 'Your Max Size':
            raise ValidationError('Please enter a username value less than the current one')
        return DefaultAccountAdapter.clean_username(self,username) # For other default validations.
```
Finally, point to the subclass in your `settings.py`
`ACCOUNT_ADAPTER = 'YourProject.adapter.UsernameMaxAdapter'`

You can refer to the `adapters.py` [file](https://github.com/pennersr/django-allauth/blob/master/allauth/account/adapter.py) in the source code and extend other modules and add a processor to change its flow. The modules such as `populate_username`, `clean_password` (which can be customized to restrict commonly used passwords) can have a custom process and flow without rewriting them.

`DefaultAccountAdapter` can be a potent tool if used in the right circumstances to intervene in allauth's default process. allauth comes with a vast variety of inbuilt settings, and they can all be viewed [here](http://django-allauth.readthedocs.io/en/latest/configuration.html). You can also download the entire source code from the link in the references.

## Setting up social login using django-allauth

### Adding the necessary apps:

As illustrated in the allauth-documentation and in the previous section we need to add the necessary apps related to logins that we are going to be using. This section demonstrates the use of Google API configuration using  `allauth.socialaccount.providers.google` and Facebook API configuration using `allauth.socialaccount.providers.facebook`. You need to add them to `INSTALLED_APPS`.

After you do so, your installed apps should look like,

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.google',
    'allauth.socialaccount.providers.facebook',
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```
Set `SOCIALACCOUNT_QUERY_EMAIL=ACCOUNT_EMAIL_REQUIRED` , `SOCIALACCOUNT_EMAIL_REQUIRED=ACCOUNT_EMAIL_REQUIRED` and `SOCIALACCOUNT_STORE_TOKENS=False`.if required and you can read more about those settings here. We will also configure some settings for Facebook and Google under `SOCIALACCOUNT_PROVIDERS`. On details about settings see the documentation [here](http://django-allauth.readthedocs.io/en/latest/providers.html#).

Your `SOCIALACCOUNT_PROVIDERS` settings should look similar to,

```
SOCIALACCOUNT_PROVIDERS = {
    'facebook': {
        'METHOD': 'oauth2',
        'SCOPE': ['email', 'public_profile', 'user_friends'],
        'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
        'INIT_PARAMS': {'cookie': True},
        'FIELDS': [
            'id',
            'email',
            'name',
            'first_name',
            'last_name',
            'verified',
            'locale',
            'timezone',
            'link',
            'gender',
            'updated_time',
        ],
        'EXCHANGE_TOKEN': True,
        'LOCALE_FUNC': 'path.to.callable',
        'VERIFIED_EMAIL': False,
        'VERSION': 'v2.12',
    },
     'google': {
        'SCOPE': [
            'profile',
            'email',
        ],
        'AUTH_PARAMS': {
            'access_type': 'online',
        }
    }
}
```
Run `python manage.py make makemigrations` and `python manage.py migrate` to create database entries. We can now create Facebook and Google API keys. I have briefly described the process below. I recommend you follow instructions on their respective official websites as their services and policies are subjected to change.

### API Creation and Configuration:

Follow the below steps and seek out extra referees or tutorials on how to do this on the internet. A brief description is below.

#### Facebook

1. Create a test app by visiting developers.facebook.com and filling in all the details.

2. Copy the App Id and Secret Key.

![Click Setup on Facebook Social Login option.
](https://thepracticaldev.s3.amazonaws.com/i/rk851jwy9steodslj43m.png)
![Leave all the other settings default and finish app creation.
](https://thepracticaldev.s3.amazonaws.com/i/jj8t48tksrj2k7ze503s.png)
![In basic settings add localhost to App Domains.
](https://thepracticaldev.s3.amazonaws.com/i/gw5hbmh0wb8r0hxw0o2g.png)

#### Google

1. Create Login API and copy the secret credentials.
2. Don’t forget to place the correct callback URL while creating the API. Place `http://localhost:8000/accounts/google/login/callback/` in callback URL.

![Adding Google API](https://thepracticaldev.s3.amazonaws.com/i/8j79nfivbkdvfbjgr9id.png)

##### Admin Configuration

1. Create a superuser(admin) by running `python manage.py createsuperuser` and fill out the details.
2. Go to `http://localhost:8000/admin` and log in to the admin console.
3. Go to the site and change `example.com` to `http://localhost:8000` in both domain name and display name.
4. Now go to Social Applications and Add social applications and fill in the details.
5. Repeat the same for Facebook and Google.

![Adding localhost to Sites](https://thepracticaldev.s3.amazonaws.com/i/3n9ssk4fsyaw30n9zf5p.png)

You are set and done. You can now go ahead and use Facebook and Google logins.

This is one of the first most comprehensive posts on dev.to. Feel free to send hugs or bugs my way.

## References and further reading:

1. [django-allauth GitHub page](https://github.com/pennersr/django-allauth)
2. [django-allauth official documentation](http://django-allauth.readthedocs.io/en/latest/)
3. [My custom templates and CSS](https://github.com/gajeshbhat/django-experiments/tree/master/allauthdemo)
4. [Stack Overflow thread on Example 1](https://stackoverflow.com/questions/50924482/django-allauth-restrict-registration-to-list-of-emails/50934047#50934047)
5. [Stack Overflow thread on Example 2](https://stackoverflow.com/questions/50548685/how-to-add-max-length-to-allauth-username/50941366#50941366)
6. [Adapters.py File in Source code](https://github.com/pennersr/django-allauth/blob/master/allauth/account/adapter.py)
7. [Facebook API](http://django-allauth.readthedocs.io/en/latest/providers.html#facebook) and [Google API](http://django-allauth.readthedocs.io/en/latest/providers.html#google) all-auth documentation.
8. [Full source code for the guide](https://github.com/gajeshbhat/django-experiments)