How to implement user authentication in Python Django?

What is authentication? On many websites, we want some method of authentication. Some ability for users to be able to log in and log out. In this blog, we are going to introduce an application that lets us interact with this authentication method using Django's builtin authentication methods.

Because Django has a whole bunch of authentication features built right into the framework that we can take advantage of , we don't need to rewrite all the logic for how do you log someone in, and what does it mean to represent the user. Django has done a whole lot of that for us.

So we'll go ahead and create an application to do that now.

Step 1: Create an app that's going to maintain users inside of any application. For example, users using the command


python manage.py startapp users

Step 2: Whenever you create a new app, go to settings.py and update Installed Apps with the new app name.


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
]

Step 3: Go to urls.py and set path for the new app urls :



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

Step 4: Now inside the users application ,all the URLs that are associated with my user's application. I need to import path, import my views, and then define some URL patterns. Here, set urls to three functions: index , login and logout. So we'll effectively have three different routes. One main index route that's just going to display information about the currently signed in user. One route for logging someone in, a form that will display the place where they can type in a user name and password to log in. And then, one route to allow users to be able to log out from this application as well.


from django.urls import path
from .import views

app_name='users'

urlpatterns = [
    path('index',views.index,name="index"),
    path('user',views.login_page,name="login"),
    path('logout',views.logout_page,name="logout"),
]

Now lets create our templates inside the application. I'll create a templates folder. Inside of which we'll just create a basic layout. This is going to be the general structure for pages in this app. Here it is called layout.html:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Users</title>
</head>
<body>
    {% block body %}
    {% endblock %}

</body>
</html>

And now that I have this HTML layout, I can go ahead and create a new file called login.html, where login.html will extend layout.html. And inside the body block, I can just display in HTML form.


login.html:

{% extends "layout.html" %}

{% block body %}
{% if message %}
    <div>{{message}}</div>
{% endif %}
<form action="{% url 'users:login' %}" method="post">
    {% csrf_token %}
    <input type="text" name="username" placeholder="Username">
    <input type="password" name="password" placeholder="Password">
    <input type="submit" value="Log in">
</form>

{% endblock %}


Here, when I'm logging in, I'm submitting a form. Generally, when you're doing that, you want to submit form data via post, especially in the case of user name and password. Because if you do this sort of thing, you don't want the user name and password to be passed in as get parameters because those show up in the URL.


Now lets login to admin and add some username and password fields . And these users, they can have additional information associated with them like firstname, lastname, email.



Then, lets write views.py for complete authentication. In views.py, we first need to think about what should happen if someone tries to access this page but they're not authenticated. How would we find that out, and what do we do in that situation? Well, let's say, if not request.user.is_authenticated, the request object that gets passed in as part of the request to every user in Django automatically has a user attribute associated with it. And that user object has an is_authenticated attribute that tells us if the user is signed in or not. If they're not signed in, we'll go ahead and HTTP response redirect them to the log in view. And in order to make this work, I'm going to need to-- from django.http import HttpResponseRedirect. And likewise, from django.urls, go ahead and import reverse as well. So if the user is not authenticated, then we're going to redirect them to the log in view, some form where the user can log themselves in.

Then in the log in view, there are two ways the log in view function could be called. One is via the get request method, meaning just show the log in form. And one is via post, submit data to the log in form as well. So if the request method is post, then get the user name which will be inside of the post data in a field called user name. And let me get the password, which will be in a field in the request.post inside of password.

Then authenticate the users using Django's built-in authenticate method. If a user is returned go ahead and login using Django's builtin login method, otherwise go back to login page displaying a message Invalid Credentials.

Now write the logout view using Django's builtin logout function. Don't forget to import

authenticate, login, logout from django.contrib.auth.

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import authenticate,login,logout
# Create your views here.

def index(request):
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse('login'))
    return render(request, "user.html")

def login_page(request):
    if request.method == "POST":
        username = request.POST['username']
        password=request.POST['password']
        user=authenticate(request,username=username,password=password)
        if user is not None:
            login(request,user)
            return HttpResponseRedirect(reverse("users:index"))
        else:
            return render(request,"userlogin.html",{
                "message":"Invalid Credentials"
            })
    return render(request,"userlogin.html")

def logout_page(request):
    logout(request)
    return render(request,'userlogin.html',{
        'message':"Logged out"
    })

So, finally if the user is authenticated , he/she will go to user.html which here shows some user information.


{% extends "layout.html" %}

{% block body %}
<h2> Welcome {{request.user.firstname}}</h2>
<ul>
    <li>Username: {{request.user.username}}</li>
    <li>Email:{{request.user.email}}</li>
</ul>

<a href="{%url 'users:logout' %}">Log Out</a>
{% endblock %}

This is Django's built in user authentication system. A system that allows us to very quickly enable users to be able to log in, log out, from our web application. Django provides many such interesting features for the developers which can be used effectively. Hope this is helpful. Thanks for reading.

61 views0 comments

Recent Posts

See All