一、会话跟踪技术

1、什么是会话跟踪技术

  可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。

  在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。

  在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:

请求银行主页;

  • 请求登录(请求参数是用户名和密码);
  • 请求转账(请求参数与转账相关的数据);
  • 请求信誉卡还款(请求参数与还款相关的数据)。

  在这会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

2、会话路径技术使用Cookie或session完成

  HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!在Web开发中,使用session来完成会话跟踪session底层依赖Cookie技术

二、Cookie

1、Cookie概述

(1)什么是Cookie?

  Cookie翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie是key-value结构,类似于一个python中的字典。

  随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器,以便服务器提取有用信息。

(2)Cookie的原理?

   Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

  

(3)查看Cookie

  

(4)Cookie规范

  • Cookie大小上限为4KB;
  • 一个服务器最多在客户端浏览器上保存20个Cookie;
  • 一个浏览器最多保存300个Cookie;

  上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但也不会出现把你硬盘占满的可能! 
  注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。

(5)Cookie与HTTP头

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:

  • Cookie:请求头,客户端发送给服务器端;
  • 格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;  Set-Cookie:响应头,服务器端发送给客户端;
  • 一个Cookie对象一个Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C

(6)Cookie的覆盖

  如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。

2、django中cookie语法

(1)设置cookie

rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect()

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...) 

  return HttpResponse()、return render()、return redirect()这三种响应体最终都是返回的HttpResponse,因此都可以设置cookie。详见后面源码解析和参数设置。

(2)获取cookie

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

  request.COOKIES实际是一个字典,封装了这次请求过来的所有cookie键值

参数:

  • default: 默认值
  • salt: 加密盐
  • max_age: 后台控制过期时间

(3)删除cookie

  响应体.delete_cookie("键值")

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

  一般清除浏览器cookie的方法:ctrl+shift+delete

(4)jquery操作cookie

  jquery操作cookie

3、Cookie版登录校验

(1)模版

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
用户名 <input type="text" name="user">
密码 <input type="text" name="pwd">
<input type="submit" value="submit">
</form>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>HI,{{ username }}</h3>
</body>
</html>

index.html

(2)模型与数据库

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)

  创建用户信息如下所示:

  

(3)视图函数

from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from app01.models import UserInfo 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() # 筛选出用户对象
print(user)
if user:
# 登录成功
# 设置cookie
response = HttpResponse("登录成功") # 也可以使用render和redirect
response.set_cookie("is_login", True)
response.set_cookie("username", user.user) # username:当前登录人的名字
return response
return render(request, "login.html") def index(request):
# 取到Cookie
print(request.COOKIES) # {'csrftoken': 'RmMPGqfuPfjfQoYRpY2RGB9IZVTM2Eockm2s88VHuFjWWH58rnKCoIaASPT16lnF', 'is_login': 'True'} is_login = request.COOKIES.get("is_login")
if is_login:
# 取到值,登录成功
username = request.COOKIES.get("username")
return render(request, "index.html", {"username": username})
else:
# 取不到值,跳转到登录页面
return redirect("/login/")

4、set_cookie参数介绍

  源码解析:class HttpResponseBase有set_cookie函数

def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
domain=None, secure=False, httponly=False):
"""
Set a cookie.
:param self:
:param key: 键
:param value: 值
:param max_age: 超长时间cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,
这个cookie会延续到浏览器关闭为止。
:param expires: 超长时间expires默认None ,cookie失效的实际日期/时间。
:param path: Cookie生效的路径,浏览器只会把cookie回传给带有该路径的页面,
这样可以避免将cookie传给站点中的其他的应用。
/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
:param domain: Cookie生效的域名你可用这个参数来构造一个跨站cookie。
如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。
如果该参数设置为 None ,cookie只能由设置它的站点读取。
:param secure: 如果设置为 True ,浏览器将通过HTTPS来回传cookie。
:param httponly: 设置为False,只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
:return:
"""

(1)max_age

  未设置则cookie持续到浏览器关闭;如设置max_age=15,代表cookie在15秒内有效。

response.set_cookie("is_login", True, max_age=15)  # 15秒有效期

(2)expires

  在指定日期失效,使用时需要引入datetime模块

import datetime
date = datetime.datetime(year=2018, month=5, day=29,hour=14,minute=32,second=10)
response.set_cookie("username", user.user, expires=date)

  到期后,index页面不再显示HI,yuan   改为显示HI,None;因为username这个cookie已经失效。

(3)path

  针对哪些路径下的视图函数可以取到设置的cookie.

response.set_cookie("username", user.user, path="/index/")

5、cookie练习

(1)案例1:显示上次访问时间。

  修改时区为北京时间,要在settings.py中设置:

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

  在index.html中添加上次登录时间标签:

<h3>HI,{{ username }}</h3>
<p>上次登录时间: {{ last_time }}</p>

  在view.py中修改index视图函数:

def index(request):
# 取到Cookie
print("index", request.COOKIES) # request.COOKIES实际是一个字典,封装了这次请求封装的所有cookie键值 is_login = request.COOKIES.get("is_login")
if is_login:
# 取到值,登录成功
username = request.COOKIES.get("username")
# 上一次访问时间,其实就是上一次访问index的时间:
import datetime
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") last_time = request.COOKIES.get("last_visit_time", "") # 每次登录取上一次登录时间,取不到默认为空
response = render(request, "index.html", {"username": username, "last_time": last_time})
response.set_cookie("last_visit_time", now)
return response
else:
# 取不到值,跳转到登录页面
return redirect("/login/")

  显示效果:

  

(2)案例2:显示上次浏览过的商品。

三、session

  Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于 session为用户浏览器独享,所以用户在访问服务器的web资源时 ,可以把各自的数据放在各自的session中,当用户再去访问该服务器中的其它web资源时,其它web资源再从用户各自的session中 取出数据为用户服务。

  

  第一步:生成随机字符串;

  第二步:服务器给浏览器的响应体里设置一个set_cookie,键为sessionid,值为对应的随机字符串。

  第三步:在django-session表中生成一条记录,session-key为随机字符串,session-data是设置的session值["username"]="yuan"。

  第四步:前面三步完成后,浏览器发第二次请求到某一视图函数中,这个函数如果要取session:request.session["username"]即可。这一步也分三步:(1)读cookie里的sessionid对应的随机字符串;(2)在django-session表中过滤session-key等于随机字符串的记录。(3)在过滤出的记录对象中取出session-data对应的字典,再.get("username")可以把对应的“yuan”取出。

1、django中的session语法

(1)基本操作

1、设置Sessions值
request.session['session_name'] ="admin"
2、获取Sessions值
session_name = request.session["session_name"]
3、删除Sessions值
del request.session["session_name"] # 删除一组键值对
4、flush()
request.session.flush() # 删除一条记录
删除当前的会话数据并删除会话的Cookie。
这用于确保前面的会话数据不可以再次被用户的浏览器访问
5、检测是否操作session值
    if "session_name" is request.session:

(2)其他操作

5、get(key, default=None)

fav_color = request.session.get('fav_color', 'red')

6、pop(key)

fav_color = request.session.pop('fav_color')

7、keys()

8、items()

9、setdefault()

10、flush() 删除当前的会话数据并删除会话的Cookie。
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。 11 用户session的随机字符串
request.session.session_key # 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否
request.session.exists("session_key") # 删除当前用户的所有Session数据
request.session.delete("session_key") request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

2、session配置

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)以秒为单位
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)

  SESSION_SAVE_EVERY_REQUEST=True:意味着每次登录都刷新SESSION_COOKIE_AGE时间计算,推迟cookie的失效时间。

3、session应用

(1)保存登录状态信息

urls.py中添加两条新路径信息:

# session
path('login_session/', views.login_session),
path('index_session/', views.index_session),

views.py中添加两个session的视图函数:

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:
# 登录成功
# 写session
request.session["is_login"] = True
request.session["username"] = user.user
"""
1、生成一个随机字符串 ,如:234sd23asdjd32
2、response.set_cookie("sessionid", 234sd23asdjd32)
3、在django-session表中创建一条记录:
session-key session-data
234sd23asdjd32 {"is_login":True, "username":"yuan"}
"""
return HttpResponse("登录成功!")
return render(request, "login.html") def index_session(request):
# 读session
print("is_login", request.session.get("is_login")) # is_login True或者输出is_login None
"""
1、request.COOKIE.get("session") # 得到随机字符串
2、在django-session表中过滤记录:
django-session.objects.filter(session-key=随机字符串).first 拿到记录对象
3、obj.session-data.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", {"username": username})

  注意:写session和读session的方法和执行步骤。

(2)保存上次登录时间

在login_session视图函数中添加:

# 添加在登录成功,写session那一块中
import datetime
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
request.session["last_visit_time"] = now

在index_session视图函数中添加:

# 在已通过登录校验部分得到last_visit_time的值
last_visit_time = request.session.get("last_visit_time")
# 将last_visit_time传入模板
return render(request, "index.html", {"username": username, "last_visit_time": last_visit_time})

(3)session的更新操作

  在前面已经讲了,用户登录时,会进行写session操作。操作步骤如下所示:

1、生成一个随机字符串 ,如:234sd23asdjd32
2、response.set_cookie("sessionid", 234sd23asdjd32)
3、在django-session表中创建一条记录:
session-key session-data
234sd23asdjd32 {"is_login":True, "username":"yuan"}

  但在实际情况下,如果用chrome浏览器反复登录yuan用户。可以发现数据库中的django_session表条数并没有增加:

  

  反复更新时,session_key保持不变,仅对session_data进行了覆盖更新。由此可知:

  服务器会首先判断能否request.COOKIE.get("sessionid")是否有结果,如果是第一次登录没有结果则执行添加操作,反之则进行更新操作。即服务器和浏览器永远只用一条记录来维持。用户切换,则将之前用户的信息完全覆盖。

  但使用firefox等浏览器登录时,会进行添加操作。因此服务器是用一条记录与浏览器对应而不是针对用户。

(4)用户注销

index.html:

<h3>HI,{{ username }}</h3>
{#<p>上次登录时间: {{ last_time }}</p>#}
<p>上次登录时间: {{ last_visit_time }}</p>
<a href="/logout/">注销</a>

urls.py:

path('logout', views.logout)

views.py:

def logout(request):
# del request.session["is_login"] # 删除了is_login这一个键值,但用来做注销并不适用
request.session.flush()
"""
1、random_str = request.COOKIE.get("sessionid")
2、django-session.object.filter(session-key=random_str).delete()
3、清cookie:response.delete_cookie("sessionid", random_str)
"""
return redirect("/login")

  注意两种session删除方法的区别!!

4、练习 

(1)验证码案例(PIL模块)

  验证码可以去识别发出请求的是人还是程序!当然,如果聪明的程序可以去分析验证码图片!但分析图片也不是一件容易的事,因为一般验证码图片都会带有干扰线,人都看不清,那么程序一定分析不出来。

四、总结章节重点

1 response.set_cookie(key,value)

2 request.COOKIE.get(key)

3 request.session[key]=value

'''
if request.COOKIE.get("sessionid"):
更新
在django—session表中创建一条记录:
session-key session-data
ltv8zy1kh5lxj1if1fcs2pqwodumr45t 更新数据
else:
1 生成随机字符串 ltv8zy1kh5lxj1if1fcs2pqwodumr45t
2 response.set_cookie("sessionid",ltv8zy1kh5lxj1if1fcs2pqwodumr45t)
3 在django—session表中创建一条记录:
session-key session-data
ltv8zy1kh5lxj1if1fcs2pqwodumr45t {"is_login":True,"username":"yuan"}
'''

4 reqeust.session[key]

'''
1 request.COOKIE.get("session") # ltv8zy1kh5lxj1if1fcs2pqwodumr45t
2 django-session表中过滤纪录:
在django—session表中创建一条记录:
session-key session-data
ltv8zy1kh5lxj1if1fcs2pqwodumr45t {"is_login":True,"username":"yuan"}
obj=django—session.objects .filter(session-key=ltv8zy1kh5lxj1if1fcs2pqwodumr45t).first()
3 obj.session-data.get("is_login")
'''

5 request.session.flush()

'''
1 randon_str=request.COOKIE.get("sessionid") 2 django-session.objects.filter(session-key=randon_str).delete() 3 response.delete_cookie("sessionid",randon_str)
'''

  

Django组件——cookie与session的更多相关文章

  1. Django组件 - cookie、session、用户认证组件

    一.cookie 1.会话跟踪技术 1)什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话 ...

  2. Django组件-cookie与session

    一.会话跟踪技术 1.什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而 ...

  3. web框架开发-Django组件cookie与session

    http协议的每一次都是无保存状态的请求,这会带来很多的不方便,比如,一刷新网页,或者进入该网页的其他页面,无法保存之前的登录状态.为了解决类似这样的问题,引入了会话跟踪 会话跟踪技术 1 什么是会话 ...

  4. 9.Django组件-cookie和session

    HTTP协议的无保存状态,对两次请求没有任何关联.每次请求都是相互独立的. 1.cookie简介 什么是会话跟踪技术我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会 ...

  5. Django 组件-cookie 与 session

    会话跟踪技术 1 什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10 ...

  6. 13 Django组件-cookie与session

    会话跟踪技术 1 什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10 ...

  7. 06 Django组件-cookie与session

    一.会话跟踪技术 1.什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而 ...

  8. Django组件——Cookie与session相关

    一,会话跟踪技术 1 什么是会话跟踪技术我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而1 ...

  9. Django 组件-cookie与session

    Cookie概述 什么叫Cookie Cookie翻译成中文是小甜点,小饼干的意思.在HTTP中它表示服务器送给客户端浏览器的小甜点.其实Cookie是key-value结构,类似于一个python中 ...

随机推荐

  1. 树状数组【洛谷P3586】 [POI2015]LOG

    P3586 [POI2015]LOG 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1 ...

  2. JDBC_时间操作_时间段和日期段查询

    import java.sql.Connection; import java.sql.DriverManager;import java.sql.PreparedStatement;import j ...

  3. IPython&Jupyter私房手册

    Jupyter是以Ipython为基础,可以极大的方便开发,对于如何使用,网上的资料都不太全.因此决定自己编写一个私房手册方便随时查找. 1. 安装和配置 安装不多说,不想折腾直接安装anaconda ...

  4. DataRow[]转DataTable

    DataRow[]有个扩展方法CopyToDataTable()

  5. 字符串变dict

    1.eval 2.json # NameError: name # 'null' is not defined # i_dict=eval(i) 这种方式,如果dict字符串中有null ,将不能变成 ...

  6. Covering(矩阵快速幂)

    Bob's school has a big playground, boys and girls always play games here after school.  To protect b ...

  7. 动态规划 70.climbing Stairs

    1. 记忆化搜索 - 自上向下的解决问题:使用vector来保存每次计算的结果,如果下次再碰到同样的需要计算的式子就不需要重复计算了. 2. 动态规划 - 自下向上的解决问题 解法一:自顶向下 解法二 ...

  8. 本地安全策略命令行secedit设置本地账户安全策略

    我们日常运行的控制台程序secpol.msc里面的内容,实质可以通过命令行完成,下面演示通过secedit命令来设置本地账号密码策略,启用密码复杂性和强制长度至少8位操作办法. ==> 新建文本 ...

  9. 1141 PAT Ranking of Institutions (25 分)

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  10. Spring4 笔记

    1. 通过 xml 赋值给 bean 1) 通过set 方法赋值 (必须要有空的构造方法) <bean id="user" class="com.test.User ...