前言
HTTP协议 是短连接、且状态的,所以在客户端向服务端发起请求后,服务端在响应头 加入cokie响应给浏览器,以此记录客户端状态;
cook是来自服务端,保存在浏览器的键值对,主要应用于用户登录;
cookie如此重要!!那么如何在Django应用cookie呢?cookie又有什么缺陷呢?
一、Django应用cookie
参数介绍
1、max_age=1 :cookie生效的时间,单位是秒
2、expires:具体过期日期
3、path=\'/\':指定那个url可以访问到cookie;‘/’是所有; path=\'/\'
4、 domain=None(None代表当前域名):指定那个域名以及它下面的二级域名(子域名)可以访问这个cookie
5、secure=False:https安全相关
6、httponly=False:限制只能通过http传输,JS无法在传输中获取和修改
设置cookie
1.普通
obj.set_cookie("tile","zhanggen",expires=value,path=\'/\' )
2.加盐
普通cookie是明文传输的,可以直接在客户端直接打开,所以需要加盐,解盐之后才能查看
obj.set_signed_cookie(\'k\',\'v\',salt="zhangge")
获取cookie
1、普通
obj.set_signed_cookie(\'k\',\'v\',salt="zhangge")
2、加盐
cookies=request.get_signed_cookie(\'k\',salt=\'zhanggen\')
最后给每个视图函数装饰cookie认证功能
from until import mysqlhelper from django.shortcuts import HttpResponse,render,redirect import json import datetime from datetime import timedelta def cookie_auth(func): def weaper(request,*args,**kwargs): cookies = request.get_signed_cookie(\'k\', salt=\'zhanggen\') if cookies == \'v\': return func(request) else: return HttpResponse(\'OK\') return weaper now = datetime.datetime.utcnow() delta = timedelta(seconds=10) def login(request): if request.method==\'GET\': return render(request,\'login.html\') else: name = request.POST.get(\'N\') pwd=request.POST.get(\'P\') if name=="alex" and pwd=="123": obj=redirect("/modal") # obj.set_cookie("tile","zhanggen",max_age=1,) value=now+delta obj.set_cookie("tile","zhanggen",expires=value,path=\'/\',domain=None,secure=False,httponly=False) obj.set_signed_cookie(\'k\',\'v\',salt="zhanggen",) return obj else: return render(request,\'login.html\') def test(request): return render(request,\'layout.html\') @cookie_auth def modal(request): sql=\'\'\' SELECT teacher.id as tid,teacher.`name`as tname,class.title FROM day64.teacher LEFT JOIN teacher_class ON day64.teacher.id=day64.teacher_class.tid LEFT JOIN day64.class ON day64.teacher_class.cid=day64.class.id; \'\'\' teacher_list= mysqlhelper.get_list(sql,[]) res={} for row in teacher_list: tid=row["tid"] if tid in res: res[tid]["titles"].append(row["title"]) else: res[tid]={\'tid\':row["tid"],\'tname\':row["tname"],\'titles\':[row["title"],]} class_list=mysqlhelper.get_list("SELECT id ,title FROM day64.class" ,[]) return render(request,\'modal.html\',{"list":res.values(),"class_list":class_list} )
二、cookie+session
1、cookie引入session:
cookie看似解决了HTTP(短连接、无状态)的会话保持问题,但把全部用户数据保存在客户端,存在安全隐患,
于是cookie+session出现了!我们可以 把关于用户的数据保存在服务端,在客户端cookie里加一个sessionID(随机字符串),
基于以上原因:cook+session组合就此作古了单单使用cookie做会话保持的方式;
2、cookie+session的工作流程:
(1)、当用户来访问服务端时,服务端生成一个随机字符串;
(2)、当用户登录成功后 把 {sessionID :随机字符串} 组织成键值对 加到 cookie里发送给用户;
(3)、服务器以发送给客户端 cookie中的随机字符串做键,用户信息做值,保存用户信息;
3、保存在服务端session数据格式
{
随机字符串 用户信息
傻狍子的随机字符串: {id:1,nam:"alex",account:1000000000 },
二狗子的随机字符串: {id:1,nam:"eric",account:10}
注意:request.session[\'name\']=‘alex’,request.session默认隐含了通过sessionID找到用户信息那一步;
所以现在设置的是用户信息的键(name)和用户信息的值(alex),删除也是如此!
4、最终得出结论了!!!
session的应用 要依赖于cookie:(session就是 cookie的变种)
(1)每次用户第一次访问服务端, 把用户的唯一字符串 session_id加到cookie里面,发送给客户端;
(2)服务器端保存 随机字符串(sessionID:{用户信息})服务端
(3)下次来通过 cookie中的sessionID(键)获取用户信息值(值)
session作用:
会话保持,记住用户的登录状态(WEB网站,分布式架构)
作用(和cookie的区别)
避免了敏感信息保存在客户端,防止客户端修改cookie信息!
5、Django应用session
def login(request): if request.method==\'GET\': return render(request,\'login.html\') else: name=request.POST.get(\'user\') pwd=request.POST.get(\'pwd\') # obj=models.Girl.objects.filter(username=name,passwprd=pwd).first() obj = models.Boy.objects.filter(username=name, passwprd=pwd).first() if obj: #1、生成随机字符串(sessionID) #2、通过cookie发送给客户端 #3、服务端保存{zhanggen随机字符串:{\'name\':\'zhanggen\'.\'email\':\'zhanggen@le.com\'}} request.session[\'name\']=obj.username #在Django 中一句话搞定 request.session[\'email\'] = \'zhanggen@le.com\' return redirect(\'/index\') else: return render(request,\'login.html\',{\'msg\':"用户名/密码错误"}) def index(request): #1、获取客户端的 sessionID #2、在服务端查找是否存在 这个sessionID #3、在服务端查看对应的key sessionID键的值中是否有name(有值就是登录过了!!) v=request.session.get(\'name\') print(v) if v: return render(request,\'index.html\',{\'msg\':v}) else:return redirect(\'/login/\')
使用参数:
def index(request): # 获取、设置、删除Session中数据 request.session[\'k1\'] request.session.get(\'k1\',None) #这样取值的不报错,没有拿None request.session[\'k1\'] = 123 request.session.setdefault(\'k1\',123) # 存在则不设置 del request.session[\'k1\'] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key
request.session.clear_expired()
#sessionID在客户端,过期后自动失效;
但session信息存储在数据库里,sessionID过期后怎么删除呢?
无法动态删过期的session,可执行这个方法!(数据库中不仅存储了session 还有该session的过期时间,这个方法就是where数据库里时间过期的session删除掉)
request.session.exists("session_key")# 检查 用户session的随机字符串 在数据库中是否
# 删除当前用户的所有Session数据
request.session.delete("session_key")
request.session.set_expiry(value) 设置session过期时间
* 如果value是个整数,session会在些秒数后失效。 *
如果value是个datatime或timedelta,session就会在这个时间后失效。 *
如果value是0,用户关闭浏览器session就会失效。 *
如果value是None,session会依赖全局session失效策略。
session配置文件
#session配置文件 SESSION_ENGINE = \'django.contrib.sessions.backends.file\' # 引擎 SESSION_FILE_PATH = 文件路径 # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T session不仅可以保存在数据库里,
- 数据库(默认)
- 缓存(memchache、redis)
- 文件
- 缓存+数据库
- 加密cookie
SESSION_COOKIE_NAME="zhanggen" # 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 = 600000 # Session的cookie失效日期(2周) 默认1209600秒 SESSION_EXPIRE_AT_BROWSER_CLOSE =True # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = True
#如果你设置了session的过期时间 30分钟后,这个参数是False30分钟过后,session准时失效
#如果设置 True,在30分钟期间有请求服务端,就不会过期!(为什么逛一晚上淘宝,也不会登出,但是不浏览器不刷新了就会自动登出)
session保存位置配置
缓存 redis memcache SESSION_ENGINE = \'django.contrib.sessions.backends.cached_db\' # 引擎 浏览器cook(相当于没有用session,又把敏感信息保存到客户端了) SESSION_ENGINE = \'django.contrib.sessions.backends.signed_cookies\' # 引擎
6、session注意事项
(1)、每个用户的保存在 服务端的sessionID保存在数据库里的 sessionID隔离不一样的,不会造成用户间的信息混淆!(淫王一问,我答错了!)
(2)、如果A用户和B用户在同一个浏览器登录,会!因为保存在浏览器的sessionID先后覆盖了!!
(3)、如果用户的cookie泄露了,别拿着你的cookie也是可以 访问服务端的,所以cookie一定要保存好。
博客链接
二龙湖浩哥:http://www.cnblogs.com/yuanchenqi/articles/7439088.html#3770465