facebook

Creating a Django Authentication App

George Anderson
Frontend and backend development guru, lover of all things computer... and cats! Hopes to make your coder life a breeze by sharing some tips and tricks of the trade.
Posted on Nov 7th 2019
This tutorial is a good place to start if you’re looking to add basic authentication to your Django application. We’ll be building an application from scratch, and use the Django authentication system to authenticate users using a username and password.

Getting Started: Configuring the Development Environment

For this tutorial, we will be using the Eclipse IDE with the CodeMix plugin installed.

If you’re looking for an IDE to take on development with frameworks like Angular, React, and Vue.js, or languages like Python and Rust, CodeMix has you covered. Codemix is compatible with all Eclipse-based IDEs and tools, such as MyEclipse, Spring Tools Suite, and JBoss Tools.


Also, we need to have Python installed in our system, so let’s be sure about having it correctly installed. It can be downloaded here.

Setting Up

We will need to create a dummy project in Eclipse and use its Terminal to execute a couple of commands for the creation of our Project.
We’ll start with a fresh Django application. Just use your favorite Python dependencies management tool. In this tutorial, I’ll use Pipenv. We can install it by using the following command in our terminal:
pip install pipenv
Let’s activate Pipenv shell to continue with Django project creation. In the opened Terminal+ execute the following command:
pipenv shell
Let’s install the Django package and create a new project:
pipenv install django
django-admin startproject DjangoAuth
The command django-admin startproject DjangoAuth will generate a bunch of files as well as including the django.contrib module, which includes the authentication support. Below is the structure of our newly created Django project:
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, we will run the following commands on our pipenv shell to create a server and run it:
./manage.py migrate
./manage.py runserver
Our development server will listen at http://127.0.0.1:8000/ as shown above.

Building the App

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

Let’s include the module’s URLs inside djangoauth/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')),

]
Now, we must create authentication templates. Templates basically contain the static parts of the desired HTML output as well as some special syntax for  the dynamic content that will be inserted. We’ll explore overriding authentication templates by creating replacement templates in a Template directory.
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
         'DIRS':[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',
            ],
        },
    },
]

WSGI_APPLICATION = 'djangoauth.wsgi.application'
These settings assume we have a templates directory in the root of our project.

Django templates make use of global context processors which basically allow us to use data between templates, in this case, we are defining the variabledjango.contrib.auth.context_processors.auth which borrows the actual authenticated user as a value, or in case no user is logged, an AnonymouseUser instance is used.

Let’s create the Templates directory, and a Registration directory with a file called login.html inside of it as shown below:
We do not want to display the default forms without any CSS style. So we’ll be using Bootstrap. Similarly, create a file base.html in Templates and add the content as 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">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Diary</title>

    <style>
        html {
            font-size: 14px;
        }
        label {
            font-weight: 700;
            display: block;
        }
        textarea:focus, input:focus{
            outline: none;
            border: none;
        }
        *:focus {
            outline: none;
        }
        .form-control:focus {
            border-color: inherit;
            -webkit-box-shadow: none;
            box-shadow: none;
        }
        .form-group {
            border-bottom-width: 1px;
            border-color: #e9ecef;
            padding-top: 1rem;
            padding-bottom: .5rem;
            color: #22292f;
            border-bottom: 1px solid #e9ecef;
        }
        .form-control {
            border: none;
            transition: background-color 5000s ease-in-out 0s;
            margin-top: .75rem;
            font-size: 100%;
            line-height: 1.15; margin-left: -10px;
        }
        .remove-form-group-border {
            border-bottom: 1px solid white;
        }
        body {
            background: #f7f6f4;
        }

        a {
            text-decoration: none;
        }

        .brand {
            text-decoration: none;
        }

        .brand > span {
            color: #633dff; font-size: 25px;
        }

        .btn {
            background: #633dff; color: white; border-color: #633dff
        }

        .btn:hover {
            color: white;
        }

    </style>
  </head>
  <body>
    {% block content %}
    {% endblock %}
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>
Now add the Content of login.html:

{% extends "base.html" %}

{% 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>CodeMix Django Tutorial</span></a>Log In</h4>
            <br>
            {% if form.errors %}
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <strong>Your username and password didn't match. Please try again.</strong>
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
            {% endif %}
            <form method="POST" action="{% url 'login' %}" class="form">
                {% csrf_token %}
                <div class="form-group">
                    <label for="password">Username</label>
                    <input name="username" type="text" class="form-control" id="id_username" placeholder="username" style="background: #f7f6f4">
                </div>
                <div class="form-group">
                    <label for="password">Password</label>
                    <input name="password" type="password" class="form-control" id="id_password" placeholder="******" style="background: #f7f6f4">
                </div>
                <div class="form-group form-check remove-form-group-border">
                    <input type="checkbox" class="form-check-input" id="remember" name="remember" style="padding-top: -5px">
                    <label for="remember" class="form-check-label" style="margin-top: -5px">Remember Me</label>
                    <p class="float-right" style="margin-top: -25px">
                        <a href="{% url 'password_reset' %}" class="no-underline text-primary">Forgot your password?</a>
                    </p>
                </div>
                <input type="hidden" name="next" value="{{ next }}">
                <button type="submit" class="btn btn-lg">Login</button>
                <p class="float-right" style="margin-top: 0px">
                </p>
            </form>
        </div>
    </div>
</div>

{% endblock %}
Once we set up everything, we can use Live Preview and see how our App will look without the need of an external browser, for this we just need specify the URL of our running App, by clicking on the URL shown the Live Preview Pane and inserting http://localhost:8000/auth/login/ as the default URL for the project.

We should see a login screen like the one below.
Live Preview Pane showing the Application running

Creating Users

Now, we need to create a new user by killing the server with CTRL+C. In the opened Terminal+, execute the following command and enter the desired login details, this will include, user, email (we can omit it) and password:
./manage.py createsuperuser

Once we have created a superuser for the app, it is a good idea to have in mind that we can manage our userbase using the default Django admin tool, we can access it via http://127.0.0.1:8000/admin/, there we can create, eliminate or just take a look at our users and their privileges on our site.

Now, run your server again and enter your credentials. We’ll be redirected to the profile page http://127.0.0.1:8000/accounts/profile/ which has nothing to return. We need to redirect the users to an actual page.

In your DjangoAuth/settings.py file add the login redirect URL and Logout URL, as shown below:

LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'
Now in your DjangoAuth/urls.py file, import the template view, the file should be something like this:
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView

urlpatterns = [
  path('admin/', admin.site.urls),
  path('auth/', include('django.contrib.auth.urls')),
  path('', TemplateView.as_view(template_name='home.html'), name='home'),
]
Python Intellisense by CodeMix

Let’s create a new file called .template/home.html This file is just an HTML file that will prompt once the user has authenticated correctly.
{% extends "base.html" %}

{% block content %}

<div class="text-black mt-10 mb-20">
    <div class="container mx-auto">
        <div class="flex justify-center flex-wrap">
            <div class="w-full lg:w-2/3 px-5">
                <h1 class="mb-5 text-center">CodeMix Tutorial</h1>
                <h2 class="text-center mb-5">Develop Angular, React, Python and Vue app with ease</h2>
                <p class="text-center">
                    {% if user.is_authenticated %}
                        <strong>{{ user.username }}</strong>, focus on developing with CodeMix
                        <a href="{% url 'logout' %}" class="btn btn-danger mt-5" style="background: red; border: 1px solid red">Logout here</a>
                    {% else %}
                        <a href="{% url 'login' %}" class="btn btn-primary">Login</a>
                    {% endif %}
                </p>
            </div>
        </div>
    </div>
</div>


{% endblock %}
And that should be it, we’ve finished adding basic authentication in our Django app. The final result should be something like this.

Conclusion

In this article, we learned how to add basic authentication from scratch to a Django application. Remember that you can take a look at our repo if you need further assistance with this project.

If you’re not already on the latest CodeMix, download it now to take advantage of all it has to offer!

Have any questions or suggestions about this article or any of our services? Let us know your thoughts via Twitter or through the CodeMix forums. Happy Coding!