Django Cookie Session Example

This example is a user login and registration example implemented with Python Django, it demos below key points.

  1. How to set/get cookie and session values in Django.
  2. How to avoid cross-site request forgery attacks.
  3. How to include other template Html pages in the Django template Html page.
  4. How to map the root url of the Django web application.
  5. How to map url exactly in Django.

1. How To Get/Set The Cookie Values In Django.

  1. Import django.http.HttpResponseRedirect class.
    django.http import HttpResponse, HttpResponseRedirect
  2. Create an instance of django.http.HttpResponseRedirect.
    response = HttpResponseRedirect('/user/login_success/')
  3. Invoke set_cookie method to set cookie name, value, and expiration time.
    response.set_cookie('user_name', user_name, 3600)
  4. Use django.http.HttpRequest.COOKIES to get cookie value.
    user_name = request.COOKIES.get('user_name','')

2. How To Get/Set The Session Values In Django.

  1. Before you can use the session in Django, you need to run migrate command to create table django_session in the project SQLite DB, otherwise, you will get no such table: django_session error message like below.
    127.0.0.1:8000/user/register
    
    OperationalError at /user/register/
    no such table: django_session
  2. You can run the migrate command in either the Django project folder in a terminal or in the PyCharm command console.
  3. Open a terminal and cd into the Django project folder, then run python3 manage.py migrateto create django_session table.
  4. Or if you coding in PyCharm, click Tools —> Run manage.py Task… menu item, then execute migrate command in the bottom command console.
    > migrate
  5. When you run the example, you can use SQLite Studio to browse the table django_session data like below. You can refer to How To Install SQLite3 On Mac to learn more.
    browse-django-session-data-in-sqlite-sutdio
  6. Use django.http.HttpRequest object session attribute to set session name,value.
    request.session['user_name'] = user_name
  7. Use django.http.HttpRequest object session attribute get method to get session value by name.
    user_name = request.session.get('user_name','')

3. How To Avoid Cross-Site Request Forgery(CSRF) Attack In Django.

  1. If you do not know what is CSRF please go to the Wikipedia CSRF page to learn.
  2. If your Django web app does not contain the below code to avoid CSRF, when you request your web page, you will get the below error page. The error message is CSRF verification failed. Request aborted.
    web-site-cross-site-request-forgery-error-page
  3. To avoid the above CSRF error, you need to add {% csrf_token %} in your Html form page.
    <form method="post" action="/user/do_login/">
          ......
          <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
          {% csrf_token %}
    </form>
  4. Then Django will create a hidden field in the result web page Html form like below. The hidden field value will be used to identify the client request.
    <input type="hidden" name="csrfmiddlewaretoken" value="4J9X89qeZS6ecrO9Z9DBkOaUOCfUpeKQZ0HxJT1xj9zyBmQRx3RMxnSMZlDkMbju">

4. How To Include Other Django Template Html Page.

  1. Use Django Html template include tag to include other template Html pages.
    {% include "./menu_bar.html" %}

5. How To Map Root Url For Django Web Application.

  1. Django defines url mapping in the application urls.py file. If you want to map Django web app root url, then just use regular expression ^$ as the url path expression.
    url(r'^$', views.home_page, name='home_page'),

6. How To Map Url Exactly In Django.

  1. One Django project can contain multiple web applications, each web application can have it’s own root web context path. In this example the Django project name is DjangoHelloWorld, and the web application name is user_register_login.
  2. We map url path user/ to web app user_register_login in the project urls.py file like below. The path starts with ^ means the request url context path should start with user/.
    url(r'^user/', include('user_register_login.urls')),
  3. So when request url http://127.0.0.1:8000/user/register/, it will find the request url path register/ mapped view function name in Django web app user_register_login‘s urls.py file.
    url(r'^register/$', views.user_register, name='user_register'),
  4. As you can see in the above url function, the path starts with ^ and end with $, this means the path should be register/ exactly. And the path register/ is relative to the web app context path user/, so the full request path should be http://127.0.0.1:8000/user/register/.

7. Django Cookie Session Example Source Code.

This example is based on the Hello World Django PyCharm Example project. It just adds a web application user_register_login in it. Below is the project source files list in PyCharm.

Please note do not forget to add app user_register_login in the project settings.py file INSTALLED_APP section like below.

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

Before dive into the source code, first, let us watch how the example looks like when executing it.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/egzgGqZon50

7.1 Project urls.py file.

  1. The file path is DjangoHelloWorld/DjangoHelloWorld/urls.py.
    from django.contrib import admin
    from django.urls import path, include
    from django.conf.urls import url
    
    urlpatterns = [
        path('admin/', admin.site.urls),
    
        path('index/', include('my_hello_world.urls')),
    
        url(r'^$', include('user_register_login.urls')),
    
        url(r'^user/', include('user_register_login.urls')),
    ]

7.2 user_register_login urls.py.

  1. The file path is DjangoHelloWorld/user_register_login/urls.py.
    from django.conf.urls import url
    from django.urls import path
    # import views from local directory.
    from . import views
    
    urlpatterns = [
    
        # do not use empty string in the url request path, it will intercept all request url with all request path value.
        # url(r'', views.home_page, name='home_page'),
    
        # if you want to intercept the django app root path request just use url path r'^$' to map it.
        # Then following url mapping will handle request http://127.0.0.1:8000/ with view function home_page.
        url(r'^$', views.home_page, name='home_page'),
    
        # Map to url http://127.0.0.1:8000/user/home/
        url(r'^home/$', views.home_page, name='home_page'),
    
        # When user browse http://localhost:8000/user/do_login, it will invoke the do_login function defined in views.py.
        url(r'^do_login/$', views.do_login, name='do_login'),
    
        # Map to url http://127.0.0.1:8000/user/login_success/, this url will be invoked after login success.
        url(r'^login_success/$', views.login_success, name='login_success'),
    
        # Map to url http://127.0.0.1:8000/user/register/
        url(r'^register/$', views.user_register, name='user_register'),
    
        # When user browse http://localhost:8000/user/do_register, it will invoke the do_register function defined in views.py.
        url(r'^do_register/$', views.do_register, name='do_register'),
    
        # Map to url http://127.0.0.1:8000/user/register_success/, this url will be invoked after register success.
        url(r'^register_success/$', views.register_success, name='register_success'),
    ]

7.3 user_register_login views.py.

  1. views.py.
    from django.shortcuts import render
    from django.http import HttpResponseRedirect
    
    # Create your views here.
    
    def home_page(request):
        return render(request, 'user_register_login/user_login.html')
    
    def do_login(request):
    
        request_method = request.method
    
        print('request_method = ' + request_method)
    
        if request_method == 'POST':
            user_name = request.POST.get('user_name','')
            user_password = request.POST.get('user_password', '')
    
            if user_name == 'dev2qa.com' and user_password == 'dev2qa.com':
                # show login success info to client browser directly.
                # return HttpResponse('Login Success!')
                print(request.path_info)
                # redirect web page to login success page.
                response = HttpResponseRedirect('/user/login_success/')
                # set cookie to transfer user name to login success page.
                response.set_cookie('user_name', user_name, 3600)
                return response
            else:
                error_json = {'error_message' : 'User name or password is not correct.'}
                return render(request, 'user_register_login/user_login.html', error_json)
        else:
            return render(request, 'user_register_login/user_login.html')
    
    def login_success(request):
        # get user name from cookie.
        user_name = request.COOKIES.get('user_name','')
        # pass user_name to display web page.
        return render(request, 'user_register_login/user_login_success.html', {'user_name':user_name})
    
    def user_register(request):
        # clear session value before register.
        request.session['user_name'] = ''
        request.session['user_password'] = ''
        request.session['user_email'] = ''
        return render(request, 'user_register_login/user_register.html', {'user_name':'','user_password':'','user_email':''})
    
    def do_register(request):
        request_method = request.method
    
        print('request_method = ' + request_method)
    
        if request_method == 'POST':
            user_name = request.POST.get('user_name', '')
            user_password = request.POST.get('user_password', '')
            user_email = request.POST.get('user_email', '')
    
            if len(user_name) > 0 and len(user_password) > 0 and len(user_email) > 0:
                # redirect web page to register success page.
                response = HttpResponseRedirect('/user/register_success/')
                # set user name, pasword and email value in session.
                request.session['user_name'] = user_name
                request.session['user_password'] = user_password
                request.session['user_email'] = user_email
                return response
            else:
                error_json = {'error_message': 'User name, password and email can not be empty.'}
                return render(request, 'user_register_login/user_register.html', error_json)
        else:
            return render(request, 'user_register_login/user_register.html')
    
    
    def register_success(request):
        # get user name, password, email value from session.
        user_name = request.session.get('user_name','')
        user_password = request.session.get('user_password', '')
        user_email = request.session.get('user_email', '')
        # pass user_name, user_password and user_email to display web page.
        return render(request, 'user_register_login/user_register_success.html', {'user_name':user_name,'user_password':user_password,'user_email':user_email})
    
    

7.4 user_register_login template html files.

7.4.1 menu_bar.html
  1. This file will be included in the other template Html file.
    <a href="/" style="margin-right: 15px">Login</a><a href="/user/register/">Register</a><br/>
7.4.2 user_login.html
  1. user_login.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>User Login Page</title>
    </head>
    <body>
    {% include "./menu_bar.html" %}
    <h3>User Login Form</h3>
    <form method="post" action="/user/do_login/">
    
        {% if error_message %}
              <font color="red">{{ error_message }}</font><br/>
        {% endif %}
        User Name: <input name="user_name" type="text" placeholder="user_name"><br/>
    
        Password: <input name="user_password" type="password" placeholder="user_password"><br/>
    
        <button type="submit">Login</button>
    
        <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
        {% csrf_token %}
    
    </form>
    </body>
    </html>
7.4.3 user_login_success.html
  1. user_login_success.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>User Login Success</title>
    </head>
    <body>
    {% include "./menu_bar.html" %}
    Hello {{ user_name }}, your user name and password is correct.
    </body>
    </html>
7.4.4 user_register.html
  1. user_register.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>User Register Page</title>
    </head>
    <body>
    {% include "./menu_bar.html" %}
    <h3>User Register Form</h3>
    <form method="post" action="/user/do_register/">
    
        {% if error_message %}
              <font color="red">{{ error_message }}</font><br/>
        {% endif %}
        User Name: <input name="user_name" type="text" placeholder="user_name" /><br/>
    
        Password: <input name="user_password" type="password" placeholder="user_password" /><br/>
    
        Email: <input name="user_email" type="text" placeholder="user_email" /><br/>
    
        <button type="submit">Register</button>
    
        <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
        {% csrf_token %}
    
    </form>
    </body>
    </html>
7.4.5 user_register_success.html
  1. user_register_success.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>User Register Success</title>
    </head>
    <body>
    {% include "./menu_bar.html" %}
    Hello {{ user_name }}, below is your register information.<br/>
    User Name : {{ user_name }}<br/>
    User Password : {{ user_password }}<br/>
    User Email : {{ user_email }}<br/>
    </body>
    </html>

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.