Categories: Django examplesPython

Setting up Authentication in Django

Authentication is a process that confirms a user’s identity. Usually, this is done through a username (or email) and a password. You enter your username (or email) and password, which allows the system to confirm your identity; Authentication means also verify user emails for retention or marketing stuff.

This tutorial is the best place if you’re looking to add authentication from scratch in your Django application. This is the preview of the app we’ll build:

We’ll start with a fresh Django application. Just use your favorite Python dependencies management tool. In this tutorial, I’ll use Pipenv.

mkdir diary
pipenv install --three
pipenv shell

Let’s install django package and create a new project:

pipenv install django
django-admin startproject diary .

manage.py startproject will generate a bunch of files as well as including the Django contrib module which includes the authentication support. By default, the required configuration is already included in the settings.py.

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth', # core of the authentication
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Now, run the following commands:

./manage.py migrate
./manage.py runserver

You should see this:

django.contrib.auth provides all you need to add authentication to your app. Let’s see what this module provides by default.

Include the module’s urls inside django_authentication/urls.py:

# django_authentication/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('django.contrib.auth.urls')),
]

The URLs provided by django.contrib.auth.urls are available at http://127.0.0.1:8000/auth/ :

Try accessing http://127.0.0.1:8000/auth/login/ you’ll see the following:

Let’s fix this the right way. We must create the authentication templates. We’ll explore overriding authentication templates by creating replacement templates in a templates directory.

# settings.py

TEMPLATES = [
    {
        # ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        # ...
    },
]

These settings assume we have a templates directory in the root of our project. Let’s create this directory and add a file called login.html.

mkdir templates
mkdir registration
touch templates/registration/login.html

I’ll not show the whole file content, just the relevant one. You can access the source code at the end of this tutorial.

Another thing is that I do not want to display the default forms without any CSS style. So I’ll be using Bootstrap.


{% extends "base.html" %} {% block content %} <form method="POST" action="{% url 'login' %}" class="form"> {% csrf_token %} <div class="form-group"> <label >

Since our app maintains the same general layout across various pages, it’s convenient to define a layout.

touch templates/base.html

The content of base.html should be something like below:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>Diary</title>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>

If you’ve set up everything, you’ll see a login. I added some default css style I used, and I have this:

The login form is ready. Then, we need to create a new user by killing the server with CTRL-C.

./manage.py createsuperuser
Username (leave blank to use 'nioperas06'):
Email address: nioperas06@gmail.com
Password:
Password (again):
Superuser created successfully.

Now, run your server again and enter the previous credentials.

You’ll be redirected to profile page http://localhost:8000/accounts/profile/ . So what if I want to redirect the user to a new shiny page?

# diary/settings.py

LOGIN_REDIRECT_URL = '/'

So, we should create a new page.

# diary/urls.py
# ...
from django.views.generic.base import TemplateView

urlpatterns = [
    # ...
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
    # ...
]

Let’s create a new file called template/home.html. This file is just a HTML file. The best file in this file is when we want to display a portion of the page only if the user is authenticated:

{% if user.is_authenticated %}
    <strong>{{ user.username }}</strong>, focus on your writing!
    <br>
    <a href="{% url 'logout' %}" class="btn btn-danger mt-5">Logout here</a>
{% else %}
    <a href="{% url 'login' %}" class="btn btn-primary">Login</a>
{% endif %}

You should add another setting into settings.py file:

# diary/settings.py

LOGOUT_REDIRECT_URL = '/'

This is where you’ll be redirecting to the home page after logout.

Login and logout are ready. Let’s try to add a signup form too.

Create a new app called accounts. An app refers to a submodule of the project.

./manage.py startapp accounts

Make sure to add the new app to the INSTALLED_APPS setting in our diary/settings.py file:

# diary/settings.py

INSTALLED_APPS = [
    # ...
    'accounts',
]

Create a new urls file in our accounts app and import a view called SignUp

from django.urls import path

from . import views


urlpatterns = [
    path('signup/', views.SignUp.as_view(), name='signup'),
]

Now for the acounts/views.py file:

# accounts/views.py
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views import generic


class SignUp(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

Create a template signup.html within the templates folder.

And add this inside:


{% extends 'base.html' %} {% block title %}Sign Up{% endblock %} {% block content %} <div class="container pt-5">     <div class="row justify-content-center">         <div class="col-lg-6 col-md-6 col-sm-8">             <h4 class="pt-2"><a href="#" class="brand"><span>Diary</span></a> — Sign Up</h4>             <form method="post">                 {% csrf_token %}                 {{ form.as_p }}                 <button type="submit" class="btn">Sign up</button>             </form>         </div>     </div> </div> {% endblock %}

You should have this:

Make sure you look at the whole source code available here.

Junior Gantin

I'm a Full Stack Developer based in Cotonou, Benin. I design, build, operate full-stack web applications. You can follow me on Twitter as @nioperas06

Share
Published by
Junior Gantin

Recent Posts

5 best Eclipse IDE themes

Eclipse is an OpenSource IDE and can be used to develop software in any language. Comparatively, It is one of…

3 days ago

15 Best NoSQL Databases

NoSQL is a non-relational database used to retrieve and store info by other means other than relations which is synonymous…

6 days ago

7 best Java machine learning library

Machine learning is a mixture of mathematical optimization and statistics, each tutorial disciplines in their very own right. Imagine if…

2 weeks ago

13 Best Bootstrap Alternatives

Bootstrap is a popular front-end development framework now days used by developers to design generic design for rapid prototyping. Along…

2 weeks ago

10 Best open-source JavaScript template engine

Imagine if you could make JavaScript development faster, and see an instant boost in your workflow. or even better: What…

3 weeks ago

XHTML vs HTML5 : Complete beginners guide

HTML is a markup language used to develop web pages and web apps. HTML5 is the latest release version of…

3 weeks ago