http协议四大特性
- 基于TCP/IP作用于应用层的协议
- 基于请求响应
- 无状态: 同一个客户端发送多次请求没有任何关联
- 无连接
会话跟踪技术
多次请求之间记录消息来弥补http无状态保存的缺点(使多次请求有联系)、
- cookie
具体一个浏览器针对一个服务器存储其消息的键值对(key=value)
- 客户端-服务端
客户端第一次访问服务端的某一个功能,比如login功能,一开始客户端的请求头里是带着空字典去访问的,访问成功后,服务器后生成一个cookie给到客户端,比如说下面的cookie:
Cookie: BAIDUID=F00480318ED42C27C35D3A2FBE2B0AD7:FG=1; BIDUPSID=F00480318ED42C27C35D3A2FBE2B0AD7; PSTM=1561713680; BD_UPN=123253; BDUSS=npyYVNyVEMwaldpTUxBV1BCUlhBfmVRTGZJclFlaENWQ0tDeGJyVFQ3a09rRnBkSVFBQUFBJCQAAAAAAAAAAAEAAABYUcuESmF2YV93aW5uZXIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4DM10OAzNdf; BD_HOME=1; H_PS_PSSID=26525_1453_21121_29522_29518_28518_29098_28838_29071
当客户端再次去访问的时候,客户端就带着这个味cookie来访问,服务器就判定了这个客户端访问过该功能,则不再生成cookie,直接让客户端访问其功能
cookie一旦生成,每次访问都会带着,除非失效,cookie是存在磁盘上的
访问不同的web服务的cookie是不同的,不同客户端访问同一个web服务的cookie也是不同的

session
保存在服务端上的键值对
服务端产生随机的串儿返回给客户端,服务端找一个地方将串儿与对应的信息存起来{'随机字符串':'敏感信息'}

客户端第一次骑牛携带的cookie:{}
服务器设置session: Request.session['username']='yuan' 设置session实现了3步
- 生成随机字符串 123ghrjsdg
- 把这次给浏览器的响应体里设置set_cookie, key是sessionid,值就是生成的随机字符串 123ghrjsdg
- 在django-session表中添加记录, session-key 是生成的随机字符串 123ghrjsdg,session-data是 {'username':'yuan'}
客户端第二次请求携带的cookie: {sessionid=123ghrjsdg}到某一个视图函数(访问某个功能)
服务器中的视图函数取session request.session['username'] 实现了3步
- 客户端携带着cookie: {sessionid=123ghrjsdg}, 视图函数会先读取到cookie中的随机字符串 123ghrjsdg
- 然后视图函数会去django-session表中找到session-key为cookie中的随机字符串 123ghrjsdg的记录
- 然后从这条记录中找到{'username':'yuan'},从而取出值,如果视图函数是登入功能的话,就可以判定这个发请求来的客户端登录成功了,而且登录名字是yuan
没有cookie,session没有任何存在的意义,当我们在浏览器上禁用了cookie,我们就无法登陆京东或者淘宝,因为服务器并没有session,验证无法通过,就无法登入了,session的查看方式在console下的application下的cookies可以查看

设置cookie
cookie语法
响应体: HttpResponse() ,render(), redirect()
设置cookie必须用响应体设置 obj.set_cookie(key,value)
设置完cookie,可以在响应头中查看 request.COOKIE.get(key) / request.COOKIE[key]
cookie超时时间: max_age(ie不支持), expires(ie支持,支持时间对象)
如果不设置超时时间,cookie就远生效
有效路径(path): 针对哪些路径下的视图函数能取到设置的cookie
代码验证
models.py
from django.db import models class Userinfo(models.Model): user=models.CharField(max_length=32) pwd=models.CharField(max_length=32)
数据库测试数据

urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^index/', views.index), ]
views.py
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') s_user = Userinfo.objects.filter(user=user, pwd=pwd).first() print(s_user.user, s_user.pwd) if s_user: # 登录成功 response = HttpResponse('登录成功') response.set_cookie('name', s_user.user) response.set_cookie('pwd', s_user.pwd, path='/index/') # 设置用户的上次访问时间 import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X') response.set_cookie('now', now) return response else: # 登录失败 pass return render(request, 'login.html') def index(request): print('index', request.COOKIES) name = request.COOKIES.get('name') now = request.COOKIES.get('now', "") if name: return render(request, 'index.html', locals()) return redirect('/login/') def test(request): print('test', request.COOKIES) return HttpResponse('test')
login.html
<body> <form action="" method="post"> {% csrf_token %} 用户名 <input type="text" name="user"> 密码 <input type="text" name="pwd"> <input type="submit" value="submit"> </form> </body>
index.html
<body> <h1>hi {{ name }}</h1> </body>
当用户访问http://127.0.0.1:8000/login/,如果验证通过,则登录成功,成功返回设置的cookies,以及可以看到返回的消息

当浏览器输入网址http://127.0.0.1:8000/index/,可以查看到在login视图函数中设置的cookies

当浏览器输入网址http://127.0.0.1:8000/test/,不可以查看login函数中设置的pwd这个cookies

案例
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^reg/', views.reg), url(r'^login/', views.login), url(r'^index/', views.index), url(r'^home/', views.home), url(r'^xxx/', views.xxx), ]
views.py
from django.shortcuts import render, HttpResponse, redirect # Create your views here. def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if username == 'lyysb' and password == '123': old_path = request.GET.get('next') if old_path: obj = redirect(old_path) else: obj = redirect('/home/') # 用户登录成功 朝浏览器设置一个cookie obj.set_cookie('name', 'lyysb') # 设置上次访问时间 import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X') obj.set_cookie('time', now) return obj return render(request, 'login.html') from functools import wraps def login_auth(func): @wraps(func) def inner(request, *args, **kwargs): print(request.get_full_path()) old_path = request.get_full_path() # 校验cookie if request.COOKIES.get('name'): return func(request, *args, **kwargs) return redirect('/login/?next=%s' % old_path) return inner @login_auth def index(request): # print(request.COOKIES.get('name')) # if request.COOKIES.get('name'): last_time = request.COOKIES.get('time',"") return render(request, 'index.html', {'last_time': last_time}) @login_auth def home(request): return HttpResponse('我是home页面,只有登陆了才能看') @login_auth def xxx(request): return HttpResponse('我是xxx页面,只有登陆了才能看')
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <script src="http://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </head> <body> <form action="" method="post"> <p>username<input type="text" name="username"></p> <p>password<input type="text" name="password"></p> <input type="submit"> </form> </body> </html>
index.html
<body> <h1>index</h1> <p>上次访问时间:{{ last_time }}</p> </body>`
设置Session
session语法
- 设置Sessions值 request.session['session_name']='admin'
- 获取Session值 session_name=request.session['session_name']
- 删除Session值 del request.session['session_name']
- Flush() 删除当前的会话数据并删除会话的Cookie 这用于确保前面的会话数据不可以再次被用户的浏览器访问
代码验证
models.py
from django.db import models class Userinfo(models.Model): user=models.CharField(max_length=32) pwd=models.CharField(max_length=32)
数据库测试数据

urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^login_session/', views.login_session), url(r'^index_session/', views.index_session), ]
views.py
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from app01.models import Userinfo 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'] = 'hppsb' import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X') request.session['now'] = now return HttpResponse('登录成功') ''' 1. 生成一个随机字符串 0ps4avkhy95v4hbh1f0bae4266zlsddd 2. response.set_cookie('sessionid',dfrtghhtyr) 3. 在django session 表中创建记录 session-key session-data 0ps4avkhy95v4hbh1f0bae4266zlsddd {'is_login':True,'username':'hhpsb'} ''' return render(request, 'login.html') def index_session(request): is_login = request.session.get('is_login') if is_login: name = request.session.get('username') now=request.session.get('now') return render(request, 'index.html', locals()) return redirect('/login_session/')
login.html
<body> <form action="" method="post"> {% csrf_token %} 用户名 <input type="text" name="user"> 密码 <input type="text" name="pwd"> <input type="submit" value="submit"> </form> </body>
index.html
<body> <h1>hi {{ name }}</h1> </body>
浏览访问http://127.0.0.1:8000/login_session/,验证通过后产生cookie

查看django_session表

浏览器访问http://127.0.0.1:8000/index_session/

更新session

更新操作,如果用户访问过页面,则第二次访问会带着sessionid这个cookie字段来访问,数据库表django_session中的session_key字段不变,如果添加新的session数据,数据库表中的session_data会变化
views.py
def index_session(request): is_login = request.session.get('is_login') if is_login: name = request.session.get('username') now=request.session.get('now') request.session['xxx']='xxx' # 把这条数据加入session,session_data字段立马变化 return render(request, 'index.html', locals()) return redirect('/login_session/')

基于session的注销功能
models.py
from django.db import models class Userinfo(models.Model): user=models.CharField(max_length=32) pwd=models.CharField(max_length=32)
数据库测试数据

urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^login_session/', views.login_session), url(r'^index_session/', views.index_session), url(r'^logout/', views.logout), ]
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'] = 'hppsb' import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X') request.session['now'] = now return redirect('/index_session/') ''' 1. 生成一个随机字符串 0ps4avkhy95v4hbh1f0bae4266zlsddd 2. response.set_cookie('sessionid',dfrtghhtyr) 3. 在django session 表中创建记录 session-key session-data 0ps4avkhy95v4hbh1f0bae4266zlsddd {'is_login':True,'username':'hhpsb'} ''' return render(request, 'login.html') def index_session(request): is_login = request.session.get('is_login') if is_login: name = request.session.get('username') now=request.session.get('now') return render(request, 'index.html', locals()) return redirect('/login_session/') def logout(request): 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) ''' return redirect('/login_session/')
login.html
<body> <form action="" method="post"> {% csrf_token %} 用户名 <input type="text" name="user"> 密码 <input type="text" name="pwd"> <input type="submit" value="submit"> </form> </body>
index.html
<body> <h1>hi {{ name }}</h1> </body>
浏览器访问http://127.0.0.1:8000/index_session/ 按注销跳转到登录页面


session的配置参数

配置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失效日期(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session, 默认修改后才保存(默认)