会话跟踪技术cookie与session——重要概念、基本用法及两个实例
基本概念
会话跟踪技术(cookie与session):在多次请求之间记录相关的信息,来弥补Http协议的“无状态保存”
Http协议的无状态保存:浏览器在访问服务器的时候,多次请求间相互独立,无法记录前一次请求的状态。
cookie将键值信息存到客户端;session将键值信息存到了服务器端。
cookie的基本操作
详见这篇博客:https://www.cnblogs.com/paulwhw/articles/10958473.html
# 注意里面的键值用逗号隔开
1、设置(response) response.set_cookie('key','value')
2、读取(request) request.COOKIES.get('key')
'''
(删除的话建议在本地浏览器删除)
'''
session的基本操作
常用的操作
1、设置session:request.session['key'] = 'value'
request.session.setdefault('k1',123) # 存在则不设置
2、读取session:request.session['key']
#这种方式最常用,既可以清除本地cookie对应的值也可以清除server端数据库中的对应记录
3、清除session:request.session.flush()
设置session时发生的三件事
1、生成一个随机字符串:session_id:xxxxx
2、加密用户的信息(比如is_login登陆状态或者用户名信息等),将这些信息加密~然后保存到数据库里面django_session表。
django_session表中有三个字段:
session_key保存着随机字符串session_id的值;session_data中保存着第2步中加密后的用户信息数据;expire_date保存着这个session到期的时间(到了这个时间点自动失效,默认为2周)。
3、最后将这个session_id保存到本地的cookie中。
读取session时发生的两件事
1、从cookie中找到sessionid的值xxxx(就是设置的3步存到本地的随机字符串的值)
2、通过这个随机字符串去server端的django_session表找到对应的那条记录,然后将session_data拿出来进行解密,得到用户设置的数据,进行逻辑判断处理。
cookie的例子
路由
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), re_path('^cookie/$',views.cookie), re_path('^index/$',views.index), re_path('^test/$',views.test), ]
models文件
from django.db import models class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32)
视图函数
from django.shortcuts import render,HttpResponse,redirect from app01.models import UserInfo def cookie(request): if request.method == 'POST': name = request.POST.get('user') pwd = request.POST.get('pwd') ret = UserInfo.objects.filter(name=name,pwd=pwd).first() if ret: #登陆成功 ''' 一、响应体: return HttpResponse() return render() return redirect() 二、三个问题: (1)一次访问成功了后面访问都带着这个cookie——前提是设置了获取cookie (2)换一个浏览器访问就变成“新的了” (3)同一个浏览器访问不同的服务器携带的cookie不同、独立的。 ''' ##设置cookie response = HttpResponse('OK') ##超时参数 max_age (单位是秒),表示多长时间以后失效 ##有效路径,表示只给某些路由下的视图函数使用——下面的例子表示只能有路径index下的视图函数访问 response.set_cookie('is_login',True,max_age=155,path='/index/') #保存当前登陆的用户信息 ##超时参数 expires(IE浏览器不支持max_age,支持这个),表示在固定的时刻失效 import datetime date = datetime.datetime(year=2019,month=8,day=11,hour=12,minute=36,second=55) response.set_cookie('username',ret.name,expires=date) return response return render(request, 'cookie.html') #如果cookie的页面登陆成功,那么此次访问index的话会携带cookie def index(request): print('index',request.COOKIES) #index {'is_login': 'True', 'csrftoken': 'DyEpXOzbKhtg5Nr8cf3mFm6JF2PuYHcdbWCzfB5eYqjfF9fn2RuGafjge7YVtuNC', 'username': 'whw'} ##获取cookie的值 is_login = request.COOKIES.get('is_login') username = request.COOKIES.get('username') ##获取上次访问时间 import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X ') last_time = request.COOKIES.get('last_visit_time') ##表示有cookie了 if is_login: response = render(request, 'index.html',{'username':username,'last_time':last_time}) response.set_cookie('last_visit_time',now) return response #否则跳转回登陆页面 else: return redirect('/cookie/') def test(request): print('test:',request.COOKIES)#只有中间件的cookie test: {'csrftoken': 'DyEpXOzbKhtg5Nr8cf3mFm6JF2PuYHcdbWCzfB5eYqjfF9fn2RuGafjge7YVtuNC', 'is_login': 'True', 'username': 'whw'} return HttpResponse('OK')
cookie.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Cookie</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名: <input type="text" name="user"> 密 码: <input type="text" name="pwd"> <input type="submit" value="提交"> </form> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> </head> <body> <p>Welcome! {{ username }}</p> <p>上次登陆时间:{{ last_time }}</p> </body> </html>
session的例子
路由
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), re_path('^session/$',views.session), re_path('^index/$',views.index), re_path('^logout/$',views.logout), ]
models文件
from django.db import models class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32)
视图函数
from django.shortcuts import render,HttpResponse,redirect from app01.models import User def session(request): if request.method == 'POST': name = request.POST.get('user') pwd = request.POST.get('pwd') ret = User.objects.filter(name=name,pwd=pwd).first() if ret: request.session['is_login'] = True request.session['username'] = ret.name ##记录上次“登陆的时间” ###注意这个时间写在登陆的逻辑里代表登陆时间,写在index的逻辑里代表访问时间 import datetime now = datetime.datetime.now().strftime('%Y-%m-%d %X') request.session['last_visit_time'] = now ''' session的存储会执行三部分内容: (1)生成随机字符串(比如是'asd') (2)响应体response:response.set_cookie('sessionid','asd') (3)在django-session表中创建一条记录(只看关键的两个): session-key(保存随机字符串) session-data(以字典新式存的上面的session设置的值:{'is_login':True,'username':(ret.name的值)}) ''' return HttpResponse('OK!') return render(request,'session.html') ### def index(request): ''' 1.获取随机字符串 request.COOKIE.get('sessionid') 2.在django-session表中过滤记录: session-key session-data XXX XXX obj = django-session.objects.filter(session-key='随机字符串') 3.从obj中取出session-data,找到对应的键值,注意需要反序列化:obj.session-data.get('is_login') ''' ##保存登陆状态信息 is_login = request.session.get('is_login') username = request.session.get('username') last_visit_time = request.session.get('last_visit_time') #登陆成功 if is_login: return render(request,'index.html',locals()) #登陆不成功跳转到登录页面 else: return redirect('/session/') ### def logout(request): # 注销——删掉代表登陆成功信息的session #删除所有的信息 # del request.session['is_login'] 这句话只能删除部分 #用下面这个 ##删除当前会话数据并删除会话的cookie ##这用于确保前面的会话数据不可以再次被用户的浏览器访问 request.session.flush() #注销后跳转到登陆的session主页面 return redirect('/session/')
session.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Session</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名: <input type="text" name="user"> 密 码: <input type="password" name="pwd"> <input type="submit" value="确认"> </form> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> </head> <body> <p>Hello! {{ username }}</p> <p>上次“登陆”时间:{{ last_visit_time }}</p> <p><a href="/logout/">注销</a></p> </body> </html>