Lab 3: Form, Authentication, Session and Cookie
Platform-Based Programming (CSGE602022) - Organized by Faculty of Computer Science Universitas Indonesia, Odd Semester 2022/2023
Learning Objectives
After completing this tutorial, you are expected to be able to:
- Understand how to submit user-provided input using
<form>
element - Understand how authentication works
- Understand the purpose of cookie and session in the context of web development
- Understand how cookie and session work
- Use cookie and session in the context of web development
Introduction to HTTP
HTTP stands for HyperText Transfer Protocol. HTTP is a protocol used to communicate between client and server. HTTP is stateless; meaning that every transaction/activity performed is considered a completely new transaction/activity, thus no previous data is stored for the current transaction/activity.
Some basic concepts about HTTP:
Client/Server: Interaction is done between client/server. The client makes a request and the server provides a response.
Stateless: Each activity (request/response) is independent.
OSI Model/Layer: The Open Systems Interconnection (OSI) model describes seven layers that computer systems use to communicate over a network. The OSI 7-layer model consists of Application Layer, Presentation Layer, Session Layer, Transport Layer, Network Layer, Data Link Layer, and Physical Layer.
Application Layer: The website runs on the application layer. The request/response process occurs at the transport layer which generally uses the TCP protocol which determines how the data will be sent. The application layer doesn't care what the transport layer does (how the data is sent, processed, etc.) because the application layer only focuses on the request and response.
The rest of the layers will be taught on Computer Networks course. You can search it by yourself if you want. 😉
Client Actions Method: This is the method used by the client when making a request. Example: GET, POST, PUT, DELETE, etc. A more detailed explanation can be read here).
Server Status Code: Is the status code given by the server when requesting a web page Example: 200 (OK), 404 (Page Not Found), 500 (Internal Server Error), etc. A more detailed explanation can be read here.
Headers: These are small pieces of information sent along with the request and response. They are useful as additional data used to process the request/response. Example: In the headers, there is
content-type:json
. This means that the type of content requested/sent isjson
. Headers also stores cookies data.
Introduction to Cookies & Session
All communication between client and server is done through HTTP protocol, where HTTP is a stateless protocol. This means that one state is not related to another (independent). This requires the client computer running the browser to establish a TCP connection to the server every time it makes a request. Without a persistent connection between the client and the server, the software on each side (endpoint) cannot rely solely on the TCP connection to perform holding state or holding session state. What does holding state mean?
For example, you want to access page A on a website that requires the visitor to be logged in to the website. Then you login to the web and successfully open page A. When you want to move to page B on the same web, without a holding state process, you will be asked to login again. That will happen every time you access a different page while still on the same web. This process of telling "who" is currently login and storing data is known as a form of client-server dialog. It is also the basis of session - a semi-permanent exchange of information. It is difficult to make HTTP do state-holding (because HTTP is a stateless protocol). Therefore, techniques are needed to overcome this problem, namely Cookie and Session.
One of the most widely used ways to perform state-holding is to use a session ID that is stored as a cookie on the client computer. The Session ID can be thought of as a token (line of characters) to recognize a unique session in a particular web application. Instead of storing all kinds of information as cookies on the client such as username, name, and password, only the Session ID is stored. This Session ID can then be mapped to a data structure on the web server side. In that data structure, you can store all the information you need. This approach is much safer for storing information about users, rather than storing it in a cookie. This way, the information cannot be misused by suspicious clients or connections. In addition, this approach is more "appropriate" if there is a lot of data to be stored. That's because cookies can only store a maximum of 4 KB of data. Imagine that you have logged in to a web/app and got a session ID (session identifier). In order to be able to do holding state on HTTP which is stateless, browsers usually send a session ID to the server on every request. That way, every time a request comes, the server will react (more or less) "Oh, this is the right person!". Then the server will look up the state information in the server memory or in the database based on the session ID obtained, and then return the requested data.
An important difference to keep in mind is that cookie data is stored on the client side, while session data is usually stored on the server side. For a more detailed discussion of stateless, stateful, cookie, and session, please read here.
Cookies | Local Storage | Sessions | |
---|---|---|---|
Capacity | 4 KB | 5 MB | 5 MB |
Browser technology | HTML4/HTML5 | HTML5 | HTML5 |
Accessibility | All window | All window | Tab specific |
Expiration time | Manually set | No expiration time | when tab is closed |
Here are some links that can expand your knowledge related to this material:
Tutorial: Creating a Registration Form
Notes: In this lab, you will use the project that you have created in the previous tutorial.
We will make the previously created wishlist page access to be restricted, with the aim that users who want to access the wishlist page must have an account and log in to the website in order to gain access.
Run the virtual environment in the project
Open
views.py
in thewishlist
folder and create a function namedregister
that accepts arequest
parameter.Import
redirect
,UserCreationForm
, andmessages
at the very top../wishlist/views.pyfrom django.shortcuts import redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messagesAdd the code snippet below to the
register
function you created earlier. It is used to automatically generate a registration form and generate a user account when data is submitted from the form../wishlist/views.pydef register(request):
form = UserCreationForm()
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Account successfully created!')
return redirect('wishlist:login')
context = {'form':form}
return render(request, 'register.html', context)Create a new HTML file named
register.html
inwishlist/templates
folder. The content ofregister.html
can be filled with the following template example../wishlist/templates/register.html{% extends 'base.html' %}
{% block meta %}
<title>Account Registration</title>
{% endblock meta %}
{% block content %}
<div class = "login">
<h1>Registration Form</h1>
<form method="POST" >
{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td><input type="submit" name="submit" value="Register"/></td>
</tr>
</table>
</form>
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock content %}Open
urls.py
in thewishlist
folder and import the function you created earlier../wishlist/urls.pyfrom wishlist.views import register # Customize with the name of the function created
Add path url to
urlpatterns
to route incoming request with matching URL pattern (i.e./register/
) to be handled byregister
function:./wishlist/urls.pypath('register/', register, name='register'), # Customize with the name of the function created
We have added an account registration form and created the register
mechanism. Next, we will create a login form for users to authenticate their accounts.
Tutorial: Creating a Login Form
Open
views.py
in thewishlist
folder and create a function namedlogin_user
that accepts arequest
parameter.Add import
authenticate
andlogin
at the very top../wishlist/views.pyfrom django.contrib.auth import authenticate, login
Add the code snippet below to the
login
function you created earlier. This piece of code serves to authenticate users who want to login../wishlist/views.pydef login_user(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('wishlist:show_wishlist')
else:
messages.info(request, 'Wrong Username or Password!')
context = {}
return render(request, 'login.html', context)Create a new HTML file with the name
login.html
in thewishlist/templates
folder. The content oflogin.html
can be filled with the following template../wishlist/templates/login.html{% extends 'base.html' %}
{% block meta %}
<title>Login</title>
{% endblock meta %}
{% block content %}
<div class = "login">
<h1>Login</h1>
<form method="POST" action="">
{% csrf_token %}
<table>
<tr>
<td>Username: </td>
<td><input type="text" name="username" placeholder="Username" class="form-control"></td>
</tr>
<tr>
<td>Password: </td>
<td><input type="password" name="password" placeholder="Password" class="form-control"></td>
</tr>
<tr>
<td></td>
<td><input class="btn login_btn" type="submit" value="Login"></td>
</tr>
</table>
</form>
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
Don't have an account? <a href="{% url 'wishlist:register' %}">Create Account</a>
</div>
{% endblock content %}Open
urls.py
in thewishlist
folder and import the function you created earlier../wishlist/urls.pyfrom wishlist.views import login_user # Customize with the name of the function created
Add path url to
urlpatterns
to associate incoming request containinglogin
URL to be handled bylogin_user
function:./wishlist/urls.pypath('login/', login_user, name='login'), # Customize with the name of the function created
We have added the account's login form and created the login
mechanism. Next, we will create a logout mechanism and add a logout button to the wishlist page.
Tutorial: Creating a Logout Function
Open
views.py
in thewishlist
folder and create a function namedlogout_user
that accepts the request parameter.Import
logout
function at the very top ofviews.py
file:./wishlist/views.pyfrom django.contrib.auth import logout
Add the code snippet below into the
logout
function you created earlier. This code snippet serves to perform the logout mechanism../wishlist/views.pydef logout_user(request):
logout(request)
return redirect('wishlist:login')Open the
wishlist.html
file in thewishlist/templates
folder.Add the code snippet below after the end tag table (
</table>
) in thewishlist.html
file. This code snippet serves to add a logout button../wishlist/templates/wishlist.html<button><a href="{% url 'wishlist:logout' %}">Logout</a></button>
Open
urls.py
in thewishlist
folder and import the function you created earlier../wishlist/urls.pyfrom wishlist.views import logout_user # Customize with the name of the function created
Add the url path into the
urlpatterns
to handle incoming request towardlogout
path:./wishlist/urls.pypath('logout/', logout_user, name='logout'), # Customize with the name of the function created
We have created a logout
mechanism and completed the authentication system on the wishlist
project. Next, we will restrict wishlist page access so that unauthenticated users cannot access the wishlist page.
Tutorial: Restricting Wishlist Page Access
Open
views.py
in thewishlist
folder and add importlogin_required
function at the very top../wishlist/views.pyfrom django.contrib.auth.decorators import login_required
Add the code
@login_required(login_url='/wishlist/login/')
above theshow_wishlist
function so that the wishlist page can only be accessed by logged in (authenticated) users../wishlist/views.py@login_required(login_url='/wishlist/login/')
def show_wishlist(request):
After restricting wishlist page access, run your Django project with python manage.py runserver
command and open http://localhost:8000/wishlist in your favorite browser to see the results.
Tutorial: Add Cookies
Now, we'll see the use of cookies with last login data and display it to wishlist page.
Please logout first if you're running your Django application and already logged in.
Open
views.py
that located inwishlist
folder and add importHttpResponseRedirect
,reverse
, anddatetime
at the top of your file../wishlist/views.pyimport datetime
from django.http import HttpResponseRedirect
from django.urls import reverseIn
login_user
function. we'll add the function to add cookie namedlast_login
to see when the was the last time a user logged in. Change the code inif user is not None
block to the following piece of code:./wishlist/views.pyif user is not None:
login(request, user) # login first
response = HttpResponseRedirect(reverse("wishlist:show_wishlist")) # create response
response.set_cookie('last_login', str(datetime.datetime.now())) # create last_login cookie and add it to response
return responseIn the
show_wishlist
function, add the snippet code belowshow_wishlist
,'last_login': request.COOKIES['last_login']
t thecontext
variable. The following example is the code that already changed:./wishlist/views.pycontext = {
'list_item': data_wishlist_item,
'name': 'Cinoy',
'last_login': request.COOKIES['last_login'],
}Change
logout_user
function to the following code snippet below. The following code will addlast_login
cookie removal mechanism when the user is logged out../wishlist/views.pydef logout_user(request):
logout(request)
response = HttpResponseRedirect(reverse('wishlist:login'))
response.delete_cookie('last_login')
return responseOpen the
wishlist.html
file and add the following code snippet below between the table and the logout button to display the last login information../wishlist/templates/wishlist.html<h5>Last Login: {{ last_login }}</h5>
Please refresh your login page (or run your Django project with the command
python manage.py runserver
if you haven't run your project yet) and try to login. The last login information will display in thewishlist
page.To see the data of
last_login
cookie, you can access the feature of inspect element and open the Application/Storage tab. Click Cookies and you'll see the available cookies data. Besideslast_login
, you can also viewsessionid
andcsrftoken
data. Here is an example of how it looks.If you logout from your application and open the cookie history, you'll see that the cookie that you created before was removed and will be remade when you login again.
The Final Word
Congratulations! You have successfully completed Tutorial 3. 😄
After you finished the whole tutorial above, I hope you now understand more about using form, authentication, session, and cookie in Django's framework.
As always, don't forget to add
, commit
, and push
the changes you made to save them to the GitHub repository before you close your job. 😉
Contributors
- Muhammad Athallah
- Muhammad Azis Husein
- Zuhal 'Alimul Hadi
- Winaldo Amadea (EN Translator)
- Firlandi A. R. Ansyari (EN Translator)