一、cookie和session的介绍
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。
问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。
我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。
总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架
二、登录应用原理
前几节的介绍中我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面。直接输入后台的url地址也可以直接访问的。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。
先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端,这个被存储在浏览端的东西就叫cookie。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以字典形式存储的,字典的唯一key就是刚才发给用户的唯一的cookie值。那么如果在服务器端查看session信息的话,理论上就会看到如下样子的字典
{'123abc':{'login':true,'username:hahaha'}}
因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。那么为什么说我们只是理论上看到这样子的字典呢?因为处于安全性的考虑,其实对于上面那个大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在服务器端也是一样被加密的。所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西
{'123abc':dasdasdasd1231231da1231231}
三、cookie的简单使用
获取cookie:如果有值就获取,如果没有则返回None
val = request.COOKIES.get('user','')
设置cookie:
expires:过期时间,是一个日期时间型
path:有效路径,设置的cookie只作用于这个路径以及子路径
max_age:过期时间,单位是秒
response = redirect('/index/') # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie date = datetime.date(year=2020,month=12,day=31) response.set_cookie('user',user_ret.name,expires=date,path='/index/')
删除cookie:
response.delete_cookie('user','user_ret.name)
基于登录验证的3次请求过程:
一共有三次请求
注意:form表单的action走的路径还是/login/
第一次请求:url:http://127.0.0.1:8080/login GET请求
第二次请求:url:http://127.0.0.1:8080/login POST请求 user pwd
第三次请求:url:http://127.0.0.1:8080/index GET请求 携带着cookie的了
所以在index页面中就会取到cookie,因为这是的index里面已经有cookie了
注意:点击提交时,完成了2次请求,一次是form表单的POST请求,一次是验证成功后return response跳转到index的GET请求
登录验证代码:
views.py

from django.shortcuts import render,HttpResponse,redirect from app01.models import * import datetime import time # Create your views here. def login(request): if request.method=='POST': print('我是post请求') user = request.POST.get('user','') pwd = request.POST.get('passwd') user_ret = Userinfo.objects.filter(name=user,pwd=pwd).first() print('用户名:',user) print(user_ret) if user_ret : response = redirect('/index/') # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie response.set_cookie('is_login',True) #max_age是以秒计算的,不支持ie date = datetime.date(year=2020,month=12,day=31) response.set_cookie('user',user_ret.name,expires=date,path='/index/') # # response.set_cookie() return response else: return HttpResponse('登录失败') print("我是get请求") return render(request,'login.html') def index(request): print('请求类型:',request.method) is_login =request.COOKIES.get('is_login') if is_login: # 登录成功后,取出cookies中设置的user username = request.COOKIES.get('user') '''显示上次登录时间: 1,取出上次登录时间last_time,如果没有,则为空 2,设置这次登录时间login_date 3,设置这次登录的last_time ''' last = request.COOKIES.get('last_time','') #1 login_date = time.strftime('%Y-%m-%d %X',time.localtime())#2 response=render(request,'index.html',{'username':username,'logindate':last}) response.set_cookie('last_time',login_date)#3 return response else: return redirect('/login/') # return render(request,'index.html')
login.html

<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Cookies设置</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名 <input type="text" name="user"> 密码 <input type="password" name="passwd"> <input type="submit"> </form> </body> </html>
index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> </head> <body> <h1>Hi,{{ username }}</h1> <h2>上次登录时间:{{ logindate }}</h2> </body> </html>
cookie存储到客户端
优点:数据存储在客户端。减轻服务端的压力,提高网站的性能
缺点:安全性不高,在客户端很容易被查看或破解用户会话信息
四、session的简单使用
1、基本操作(需要掌握的)
1、设置session值 request.session["session_name"]="admin" 2、获取session值 session_name = request.session("session_name") 3、删除session值 del request.session["session_name"] 删除一组键值对 request.session.flush() 删除一条记录 4、检测是否操作session值 if "session_name" in request.session:
其他操作

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() 函数中就会调用它。 用户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失效策略。
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技术,首次登录后,会针对客户端(不同的浏览器,就是不同的客户端),生成一个唯一的sessionid
如果后续使用不同的用户,在相同的客户端(浏览器)登录,那么只会更新session_data中的输入,而不是重新生成sessionid
session流程解析:
1,登录成功后,会在服务器上生成session信息,格式为{'key':value}的字典,包括sessionid,session_data,session_expire
2,生成的sessionid会发送到浏览器上的cookies中,下次登录的时候,浏览器会带着这sessionid发送请求,如果sessionid在服务器中有值(说明还未到过期时间),就可以取出session_data
3,同一个浏览器(客户端),登录不同的用户,会直接删除掉上一次用户的session信息.但是sessionid不会发生改变