django session tracking technology

Keywords: Python Session Django Database Java

Catalog

Session tracking technology in django

What is Session Tracking Technology

First, we need to understand what conversation is. We can think of a session as a meeting between the client and the server, during which there are many requests and responses. For example, if you call 10086 customer service, then you are the client, 10086 customer service is the server, then a meeting is your chat process during the call. Until one party hangs up, it means the end of the conversation. During your call, you will send multiple requests to 10086, and then these requests will be saved in a session.

In Java Web, when the client makes the first request to the server, the session begins until the client closes the browser session.

Session tracking is a technique in which multiple requests in a session need to share data. For example, in a session, the request is as follows:

  • Request Bank Home Page
  • Request login (request parameter is username and password)
  • Request Transfer (Request Parameters and Transfer-related Data)
  • Request for credit card repayment (request parameters and repayment-related data)

In the above session, the current user's information must be shared in the session, because the login is zhangsan, so the transfer and repayment must be Zhangsan user's transfer and repayment, which means that we must have the ability to share data in the process of a session.

HTTP Stateless Protocol

HTTP protocol is a stateless protocol that does not save state. HTTP protocol itself does not save the communication state between request and response. That is to say, at the level of HTTP, the protocol does not persist requests or responses that have been sent.

With HTTP protocol, whenever a new request is sent, a corresponding new response will be generated. The protocol itself does not retain all previous requests or information in response to messages. This is in order to deal with a large number of transactions faster and ensure the scalability of the protocol, and specifically designed the HTTP protocol so simple.

However, with the continuous development of the web, business processing becomes more and more difficult because of statelessness. For example, we just mentioned the question of requesting bank, landing, transfer and repayment. Although HTTP is a stateless protocol, cookie technology is introduced in order to achieve the desired stateless function. With cookies and HTTP protocol communication, you can manage state.

Cookie overview

What is cookie?

Cook translated into Chinese means "little dessert" or "little biscuit". In HTTP, it represents a small dessert sent from the server to the client. In fact, cookie is a key-value structure, which is similar to python's dictionary. As the server-side response is sent to the client browser, the client browser then saves the cookie and sends it to the server the next time it visits the server.

Cookies are created on the server side and then sent to the client by a key-value pair in response. The client saves the cookie and annotates the source of the cookie. When the client makes a request to the server, all the cookies of the server are included in the request and sent to the server so that the server can identify the client.

Let's look at cookie s at the code level.

First we need to create a new project and then set the routing rules:

urls.py

from app01 import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
]

views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.


def login(request):
    return render(request, 'login.html')

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login page</title>
</head>
<body>
    <form action="" method="post">
        {% csrf_token %}
        //User name < input type = "text" name = "user">
        //Password < input type= "text" name= "pwd">
        <input type="submit" value="submit">
    </form>
</body>
</html>

Then create the model class in model.py

from django.db import models

# Create your models here.


class UserInfo(models.Model):
    user = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)

Use the database migration command to generate the database:

python3 manage.py makemigrations

python3 manage.py migrate

Finally, two records are inserted into the database:

So when we run the whole project, when we enter the username and password correctly, then set up a cookie in the browser and respond to the client, then we need to judge in views.py:

from django.shortcuts import render,HttpResponse,redirect
from app01.models import UserInfo
# Create your views here.


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        
        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            response = HttpResponse('Landing successfully')
            response.set_cookie({'is_login': True})
            return response
    
    return render(request, 'login.html')

Now let's take a look at the response after the browser enters the correct user and password:

At this time, the cookie has been placed in the response body. When the client sends a request to the server, it will carry the cookie. When we refresh the interface, we can see that the cookie is carried:

Then we can imitate a website, if you have logged in, then enter the index interface, if not, then force the jump to the login interface. First we need to write a routing rule:

urls.py

from django.contrib import admin
from django.urls import path
from app01 import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
]

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01.models import UserInfo
# Create your views here.


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            response = HttpResponse('Landing successfully')
            response.set_cookie('is_login', True)
            response.set_cookie('username', user.user)
            return response

    return render(request, 'login.html')


def index(request):
    is_login = request.COOKIES.get('is_login')
    if is_login:
        username = request.COOKIES.get('username')
        return render(request, 'index.html', locals())
    else:
        return redirect('/login/')

At this point, views.py is when the user login interface login, the system will set cookie s to record the current status and login username and then respond to the client, and then when the user visits the index interface, first to determine whether the user is logged in, if there is no login, then redirect to the login page, if the login, then jump out of the welcome interface.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h3>This is the main interface.</h3>
    <p>hello,{{ username }}</p>
</body>
</html>

So the following picture is the cookie that the browser accesses index:

cookie source code

class HttpResponseBase:
    def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
                   domain=None, secure=False, httponly=False, samesite=None):
        """
        Set a cookie.

        ``expires`` can be:
        - a string in the correct format,
        - a naive ``datetime.datetime`` object in UTC,
        - an aware ``datetime.datetime`` object in any time zone.
        If it is a ``datetime.datetime`` object then calculate ``max_age``.
        """
        self.cookies[key] = value
        if expires is not None:
            if isinstance(expires, datetime.datetime):
                if timezone.is_aware(expires):
                    expires = timezone.make_naive(expires, timezone.utc)
                delta = expires - expires.utcnow()
                # Add one second so the date matches exactly (a fraction of
                # time gets lost between converting to a timedelta and
                # then the date string).
                delta = delta + datetime.timedelta(seconds=1)
                # Just set max_age - the max_age logic will set expires.
                expires = None
                max_age = max(0, delta.days * 86400 + delta.seconds)
            else:
                self.cookies[key]['expires'] = expires
        else:
            self.cookies[key]['expires'] = ''
        if max_age is not None:
            self.cookies[key]['max-age'] = max_age
            # IE requires expires, so set it if hasn't been already.
            if not expires:
                self.cookies[key]['expires'] = http_date(time.time() + max_age)
        if path is not None:
            self.cookies[key]['path'] = path
        if domain is not None:
            self.cookies[key]['domain'] = domain
        if secure:
            self.cookies[key]['secure'] = True
        if httponly:
            self.cookies[key]['httponly'] = True
        if samesite:
            if samesite.lower() not in ('lax', 'strict'):
                raise ValueError('samesite must be "lax" or "strict".')
            self.cookies[key]['samesite'] = samesite

From this source code, we can see that besides setting cookie by key-value parameter in response volume, there are other parameters, such as super-long max_age, path of cookie in effect, and so on.

cookie Extra Long Time

Sometimes we want the cookie to expire after the user logs on to a website for a period of time, so we can set it up for an extended period of time.

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01.models import UserInfo
# Create your views here.


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            response = HttpResponse('Landing successfully')
            response.set_cookie('is_login', True, max_age=20)  # Super long time
            response.set_cookie('username', user.user)
            return response

    return render(request, 'login.html')


def index(request):
    is_login = request.COOKIES.get('is_login')
    if is_login:
        username = request.COOKIES.get('username')
        return render(request, 'index.html', locals())
    else:
        return redirect('/login/')

Then when our users log on to the login page, they go to the index interface and wait 15 seconds to redirect to the login interface automatically.

cookie Extra Long Time

expires defaults to None, the actual date/time of cookie expiration.

Unlike max_age, this is a string to write time.

views.py

import datetime
date = datetime.datetime.strftime(year=2018, month=11, day=21, hour=3, minute=51, second=0)  # East eight district

response.set_cookie('is_login', True, expires=date)

This means that the cookie expires at 11:51:00 a.m. on November 22, 2018. You can test it yourself. I won't demonstrate it.

Cook Effective Path

In the path where cookies work, browsers will only pass cookies back to pages with that path, thus avoiding passing cookies to other applications on the site. That is, if my index page needs cookies, then I just need to set this page after the path, and the rest is not required.

views.py

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            response = HttpResponse('Landing successfully')
            import datetime
            # date = datetime.datetime.strftime(year=2018, month=11, day=21, hour=3, minute=51, second=0)  # East eight district

            response.set_cookie('is_login', True, path='/login/')
            response.set_cookie('username', user.user)
            return response

    return render(request, 'login.html')

At this point, the path we set is the login page. In order to verify the effect, when we input the correct information, when we enter the address into the index interface again, because the cookie effective path has no index, it will automatically jump to the login page.

There will be no demonstration at this time.

delete cookie

response.delete_cookie("cookie_key",path="/",domain=name)

session

Session is a server-side technology. By using this technology, the server can create a unique session object for each user's browser at run time. Because session is unique for user's browser, users can store their data in their respective session tables when accessing server's web resources. When users visit other web resources in the server, they can store their data in their own session tables. Other Web resources retrieve data from users'sessions to serve users.

Why use session instead of cookie

Session is based on cookie session tracking, cookies stored in the client will pose a threat to the user's data once lost.

Let's take a look at cookie preservation:

When we enter the correct account number and password, the cookie set by the server-side response body will be passed to the client, so the client will request the cookie when it requests again, because it is plaintext and stored in the browser will become very unsafe.

So let's see what session does.

First, set two routing rules views.py:

path('login_session', views.login_session),
path('index_session', views.index_session),

Set the view function views.py at the same time.

# session
def login_session(request):
    return render(request, 'login.html')


def index_session(request):
    return render(request, 'index.html')

So how does session differ from cookie s?

views.py

def login_session(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            request.session['is_login'] = True
            request.session['username'] = user.user

            return HttpResponse('Landing successfully')
    return render(request, 'login.html')

When we visit the browser, we can see the session ID at this time:

The difference here is that session s and cookie s are created in different steps:

  1. First, the server generates a random string 123dfdf
  2. Then use the statement to create session id: request. set_cookid ('session id','123 dfdf)
  3. Finally, a record is created in the django_session table: session ID session_data

Then the last thing to return to the client is a session ID. When the client browser requests the server again, the server will look up such a record in the djano_session table according to the session ID. When we create the database, the django_session table has been created automatically.

Now let's set up a view function to see how session data is found:

views.py

def index_session(request):
    print(request.session.get('is_login'))
    is_login = request.session.get('is_login')
    if not is_login:
        return redirect('/login_session/')

    username = request.session.get('username')

    return render(request, 'index.html', locals())

session to find data is also a three-step process, the first step is to confirm whether it is the first visit, if so, add entries record, if not update operation:?

  1. First find the session ID
  2. Find this record in the django_session table by session ID
  3. Finally, session_data is obtained

Other methods of session

Delete session value: del request.session['username']

views.py

def index_session(request):

    print(request.session.get('is_login'))
    del request.session['username']
    is_login = request.session.get('is_login')
    if not is_login:
        return redirect('/login_session/')

    # username = request.session.get('username')

    return render(request, 'index.html', locals())

Then when we visit login_session and then index_session, we delete the username, and then refresh the interface like this:

flush(): Delete the current session data and delete the Cookie of the session.

logout.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h3>This is the main interface.</h3>
    <p>hello,{{ username }}</p>
    <a href="/logout/">Cancellation</a>
</body>
</html>

views.py

def logout(request):
    request.session.flush()

    return redirect('/login_session/')

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h3>This is the main interface.</h3>
    <p>hello,{{ username }}</p>
    <a href="/logout/">Cancellation</a>
</body>
</html>

At this point, click the logout label, and the cookie of the current session will be deleted.

session settings

Session is supported by default in django, and Session data is stored in database by default, that is, django_session table.

Configure settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # Engine (default)
   
SESSION_COOKIE_NAME = "sessionid"                       # Session cookie s are saved on browsers as key, i.e. session ID = random string (default)
SESSION_COOKIE_PATH = "/"                               # Session cookie saved path (default)
SESSION_COOKIE_DOMAIN = None                             # Session cookie saved domain name (default)
SESSION_COOKIE_SECURE = False                            # Whether Https transfers cookie s (default)
SESSION_COOKIE_HTTPONLY = True                           # Whether Session cookie s only support http transport (default)
SESSION_COOKIE_AGE = 1209600                             # Session cookie expiration date (2 weeks) (default)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # Whether to close the browser to expire Session (default)
SESSION_SAVE_EVERY_REQUEST = False                       # Whether to save Session for each request, after default modification (default)

Last logon time based on session

views.py

def login_session(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = UserInfo.objects.filter(user=user, pwd=pwd).first()
        if user:
            request.session['is_login'] = True
            request.session['username'] = user.user

            import datetime
            now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            request.session['time'] = now

            return HttpResponse('Landing successfully')
    return render(request, 'login.html')

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h3>This is the main interface.</h3>
{#    <p>hello,{{ username }}</p>#}
    <p>Last landing time:{{ time }}</p>
    <a href="/logout/">Cancellation</a>
</body>
</html>

cookie-Based is a similar approach.

Posted by sumolotokai on Mon, 06 May 2019 07:20:39 -0700