Now , If a website doesn't remember who you are and your previous activities on the website in some way , What is lost is the usability and convenience of the website , Then it is likely to lead to the streaming of website users , So remember a user ( A more professional term is User tracking ) For the vast majority of Web It is a necessary function for applications .
On the server side , We want to remember that the easiest way for a user is to create an object , Through this object, you can save all user related information , This object is what we often say session( User session object ). So here comes the question ,HTTP Itself is a connectionless ( During each request and response , Once the server finishes responding to the client request, it disconnects )、 No state ( When the client sends a request to the server again , The server cannot know any previous information about this client ) The agreement , Even if the server passes session Object preserves user data , You also have to determine in some way which one the current request and the one saved before session It's related . I believe many people can think of , We can give each session Object is assigned a globally unique identifier to identify session object , Let's call it sessionid, Every time a client makes a request , Just take this sessionid, There is a way to find the corresponding session object , Thus, the user's information can be remembered between two requests , That's what we said before about user tracking .
Let the client remember and bring it with each request sessionid There are also the following practices :
URL rewrite . So-called URL Rewriting is in URL Middle carry sessionid, for example :http://www.example.com/index.html?sessionid=123456
, The server obtains sessionid Parameter value to get the corresponding session object .
Hidden fields ( Implicit form fields ). When you submit the form , You can send additional data to the server by setting hidden fields in the form . for example :<input type="hidden" name="sessionid" value="123456">
.
The local store . Browsers now support a variety of local storage solutions , Include :cookie、localStorage、sessionStorage、IndexedDB etc. . In these programs ,cookie It is the scheme with the longest history and the most criticized , It is also a scheme that we will explain to you first . To put it simply ,cookie It is a kind of data saved in the browser temporary file in the form of key value pairs , At every request , The request header will carry the cookie To the server , So as long as sessionid write in cookie, The next time a request is made, the server only needs to read cookie You can get this sessionid, As shown in the figure below .
stay HTML5 The essentials of the times , except cookie, You can also use new local storage API To save the data , Just mentioned localStorage、sessionStorage、IndexedDB Technology , As shown in the figure below .
Creating Django Project time , Default profile settings.py
A file named SessionMiddleware
Middleware ( We will explain the knowledge of Middleware in detail in the next chapter , Here you only need to know its existence ), Because of the existence of this middleware , We can directly request the object's session
Property to manipulate the session object .session
Attribute is a container object that can read and write data like a dictionary , So we can use “ Key value pair ” To preserve user data . meanwhile ,SessionMiddleware
The middleware also encapsulates the right cookie The operation of , stay cookie It's preserved in sessionid, As we described before .
By default ,Django take session The serialized data is saved in the relational database , stay Django 1.6 In later versions , The default way to serialize data is JSON serialize , It has been used before Pickle serialize .JSON Serialization and Pickle The difference between serialization is that the former serializes objects into strings ( Character form ), The latter serializes objects into byte strings ( Binary form ), For safety reasons ,JSON Sequenced to present Django By default, the framework serializes data , This requires us to save in session The data in must be able to JSON Serialized , Otherwise, an exception will be thrown . There is one more thing to be said , Use a relational database to save session Data in is not the best choice most of the time , Because the database may bear great pressure and become the bottleneck of system performance , In the following chapters, we will tell you how to session The data of is saved to the cache service .
We continue to improve the previous voting Application , In the previous chapter, we implemented user login and registration , Let's first improve the check of verification code when logging in .
def get_captcha(request):
""" Verification Code """
captcha_text = random_captcha_text()
request.session['captcha'] = captcha_text
image_data = Captcha.instance().generate(captcha_text)
return HttpResponse(image_data, content_type='image/png')
Pay attention to the... In the code above 4 That's ok , We save the randomly generated verification code string to session in , Later when the user logs in , We want to save it in session Compare the verification code string in with the verification code string entered by the user , If the user enters the correct verification code, the subsequent login process can be executed , The code is as follows .
def login(request: HttpRequest):
""" Sign in """
hint = ''
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
# Verify the correctness of the verification code
captcha_from_user = form.cleaned_data['captcha']
captcha_from_sess = request.session.get('captcha', '')
if captcha_from_sess.lower() != captcha_from_user.lower():
hint = ' Please enter the correct verification code '
else:
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = User.objects.filter(username=username, password=password).first()
if user:
# Save the user number and user name in session in
request.session['userid'] = user.no
request.session['username'] = user.username
return redirect('/')
else:
hint = ' Wrong user name or password '
else:
hint = ' Please enter valid login information '
return render(request, 'login.html', {
'hint': hint})
In the above code , We have set that after successful login, we will session Save the user's number in (userid
) And the user name (username
), The page will be redirected to the home page . Next, we can slightly adjust the code of the home page , The user name of the login user is displayed in the upper right corner of the page . We wrote this code as a separate code named header.html Of HTML file , On the home page, you can click <body>
Add... To the tag {% include 'header.html' %}
To include this page , The code is as follows .
<div class="user">
{% if request.session.userid %}
<span>{
{ request.session.username }}</span>
<a href="/logout"> Cancellation </a>
{% else %}
<a href="/login"> Sign in </a>
{% endif %}
<a href="/register"> register </a>
</div>
If the user is not logged in , The page will display hyperlinks for login and registration ; After the user logs in successfully , The user name and login link will be displayed on the page , The view function corresponding to the logout link is as follows ,URL The mapping of is similar to that mentioned before , I won't repeat .
def logout(request):
""" Cancellation """
request.session.flush()
return redirect('/')
The above code passes through session object flush
Methods to destroy session, On the one hand, it clears the server session Object to save user data , On the one hand, it will be saved in the browser cookie Medium sessionid Delete the , Later we will discuss how to read and write cookie The operation of .
We can use the database named django_session
To find all session, The structure of the table is as follows :
among , The first 1 Columns are browsers cookie Stored in the sessionid; The first 2 The column goes through BASE64 Encoding session Data in , If you use Python Of base64
Decode it , The decoding process and results are as follows .
>>> import base64
>>> base64.b64decode('MmI4YzViYjJhOGMyMDJkY2M5Yzg3ZWIyZGViZmUzYmYxNzdlNDdmZjp7ImNhcHRjaGEiOiJzS3d0Iiwibm8iOjEsInVzZXJuYW1lIjoiamFja2ZydWVkIn0=')
'2b8c5bb2a8c202dcc9c87eb2debfe3bf177e47ff:{"captcha":"sKwt","no":1,"username":"jackfrued"}'
The first 3 The column is session The expiration time of ,session After expiration, the browser saves cookie Medium sessionid It will fail. , But the corresponding record in the database will still exist , If you want to clear expired data , You can use the following command .
python manage.py clearsessions
Django Frame default session The expiration time is two weeks (1209600 second ), If you want to change this time , You can add the following code to the configuration file of the project .
# The timeout time of the configuration session is 1 God (86400 second )
SESSION_COOKIE_AGE = 86400
Many applications that require high security must expire their sessions when the browser window is closed , No longer retain any user information , If you want to expire the session when you close the browser window (cookie Medium sessionid invalid ), You can add the configuration shown below .
# Set to True When closing the browser window session Expire on
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
If you don't want to session The data of is saved in the database , You can put it in the cache , The corresponding configuration is as follows , The configuration and use of cache will be explained later .
# Configure to store session objects in the cache
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# Configure which set of cache to use to save the session
SESSION_CACHE_ALIAS = 'default'
If you want to modify session The default serialization method of data , You can change the default JSONSerializer
It is amended as follows PickleSerializer
.
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
Django Packaged HttpRequest
and HttpResponse
Objects provide read and write cookie The operation of .
HttpRequest Encapsulated properties and methods :
COOKIES
attribute - This attribute contains HTTP Request to carry all cookie.get_signed_cookie
Method - Get signed cookie, If signature verification fails , Will produce BadSignature
abnormal .HttpResponse The way of encapsulation :
set_cookie
Method - This method can set a set of key value pairs and eventually write them to the browser .set_signed_cookie
Method - Similar to the above method , But it will be right cookie Signature to achieve tamper proof effect . Because if you tamper cookie Data in , In don't know secret key and salt In this case, a valid signature cannot be generated , So the server is reading cookie It will be found that the data is inconsistent with the signature, resulting in BadSignature
abnormal . It should be noted that , The key mentioned here is that we are Django Specified in the project configuration file SECRET_KEY
, Salt is a string set in the program , You can set whatever you want , As long as it is a valid string .The method mentioned above , If you don't know their specific usage , You can check it yourself Django Of Official documents , There is no information that can tell you how to use these methods more clearly than official documents .
We just said , Activate SessionMiddleware
after , Every HttpRequest
Objects are bound to one session attribute , It is a dictionary like object , In addition to saving user data, it also provides the ability to detect whether the browser supports cookie Methods , Include :
set_test_cookie
Method - Set the for testing cookie.test_cookie_worked
Method - Testing cookie Whether the work .delete_test_cookie
Method - Delete for testing cookie.set_expiry
Method - Set the expiration time of the session .get_expire_age
/get_expire_date
Method - Get the expiration time of the session .clear_expired
Method - Clean up expired sessions .The following is to check whether the browser supports cookie Code for .
def login(request):
if request.method == 'POST':
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
# Add your code to perform login process here
else:
return HttpResponse("Please enable cookies and try again.")
request.session.set_test_cookie()
return render_to_response('login.html')
We said before ,cookie My reputation has never been very good , Of course, we will not be in the actual development cookie Save sensitive information of users in ( Such as the user's password 、 Account number of credit card, etc ) Of , And kept in cookie Generally, the data in will also be encoded and signed . even so ,HTML5 It is also given in to replace cookie Technical solution , One of the most widely used is localStorage and sessionStorage, I believe you can tell the difference from the name , Stored in localStorage
The data can be kept for a long time ; And stored in sessionStorage
The data will be cleared when the browser closes . About these cookie Use of substitutes , I suggest you check MDN To understand .