Django框架-cookie与session
一、cookie是什么?
源起:由于http协议无法保持状态的特征,导致服务器无法辨识访问者,所以通过创建cookie的方式来保存状态。
工作原理:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个访问者是‘谁’了。
缺陷:cookie本身最大支持4096字节,以及cookie本身保存再客户端,可能被拦截或窃取,安全性低。
定义:cookie具体指的是一段小信息,它是服务器发送出来存放在浏览器存上的一组组键值对(浏览器可以不设置)下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
cookie单位:以浏览器为单位,不是以用户为单位,一个浏览器对应一个cookie
常见作用:登录状态保存
默认清空下,关闭浏览器,自动清空cookie
查看cookie:我们使用chrome浏览器,打开开发者工具,如下图
二、Django中如何操作cookie?
1、设置cookie
前提:必须是HttpResponse对象来操作cookie【即可以用render,redirect,HttpResponse】
为什么必须是response对象设置cookie?
设置cookie本质是设置一个响应头:set_cookie
因为cookie是服务器给前端的一个响应,本质上是设置一个响应头set_cookie,值为设置的key和value,所以只能通过返回的response对象去设置;
就像redirect重定向一样本质是设置一个location响应头,让浏览器再次按地址发送请求
rep = HttpResponse(....) rep = render(request, .....) rep = redirect(path) rep.set_cookie(key,value,....) rep.set_signed_cookie(key,value,salt='加密盐’,....)
参数:
- key,键
- value='' , 值
- max_age = None , 超时时间,单位为秒【表示登录后,切换到其它需要登录页面,多久不用再登录】
- expires = None ,超时时间,主要针对的是IE浏览器设置超时时间的参数
- path=‘/’ ,Cookie生效的路径,/ 表示根路径,根路径的cookie可以被任何url的页面访问,默认为根,不需要改。
- domain = None , Cookie生效的域名
- secure = False, https传输
- httponly=False 只能http协议传输,无法被js获取(底层抓包工具可以获取也可以被覆盖)
2、获取cookie
request.COOKIES['key']
request.COOKIES.get('key', '') request.get_signed_cookie('key', default=raise_error, salt='' , max_age = None)
get_signed_cookie方法的参数:
- default:默认值
- salt: 加密盐
- max_age: 后台控制过期时间
3、删除cookie
def logout(request): rep = redirect('/login/') rep.delete_cookie('is_login') # 删除用户浏览器上之前设置的user的cookie值 return rep
三、Django中如何操作session?
1、什么是session?
源起:因cookie是存放在本地,安全性低,cookie发送给服务器是放在http请求头中的,因url长度有限制,从而导致cookie不能无限大,有限制,一般最大4k,数据如果太大将极大降低网路传输效率和增加服务器端程序处理的难度,故出现sessio。
定义:是一种将会话状态保存在服务端的技术,客户端需要接收,记忆和回送session的会话标识号,session依赖cookie来传递会话标识号。
一个cookie对应一个session
session依赖于cookie
也是一组组键值对,将cookie返回给浏览器
session通过设置cookie识别不同的用户,对应的session里保存私密的信息及可超过4096字节的文本。
cookie和session其实是共通性的东西,不限于语言和框架。
session产生的流程:
1、用户打开浏览器,访问某个网站时,服务器就会在服务器的内存为该浏览器分配一个空间,该空间被这个浏览器独占,这个空间就是session空间。
2、给该浏览器设置一个cookie (其值由服务器随机生成一个字符串给这个cookie,保证其唯一)
3、session中存放要存的数据(键值对)【设置的session并不是cookie的值】
4、返回给浏览器cookie
Session的跟踪机制 1.Servlet API规范中定义了一个HttpSession接口,HttpSession接口定义了各种管理和操作会话状态的方法。 2.HttpSession对象是保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象。 3.WEB服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客户端访问某个能与客户端开启会话的Servlet程序时,WEB应用程序才会创建一个与该客户端对应的HttpSession对象。 4.WEB服务器为HttpSession对象分配一个独一无二的会话标识号,然后在响应消息中将这个会话标识号传递给客户端。客户端需要记住会话标识号,并在后续的每次访问请求中都把这个会话标识号传送给WEB服务器,WEB服务器端程序依据回传的会话标识号就知道这次请求是哪个客户端发出的,从而选择与之对应的HttpSession对象
session作用:
1、网上商城中的购物车
2、保存登录用户的信息
3、将某些数据放入到session中,供同一用户的各个页面使用
4、防止用户非法登录到某个页面
为什么session是通过request获取和设置?
因为session依赖于cookie,而cookie只能从request拿到,所以session就只能通过request获取
2、设置session
request.session['is_login'] = 'True'
注:session就是一个字典格式,将想要存的数据按key:value形式存即可
3、获取session
request.session.get('key', '')
4、Django中的session相关方法
# 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',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的key request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查会话session的key在数据库中是否存在 request.session.exists("session_key") # 删除当前会话的所有Session数据 request.session.delete() # 删除当前的会话数据并删除会话的Cookie。 request.session.flush() 这用于确保前面的会话数据不可以再次被用户的浏览器访问 例如,django.contrib.auth.logout() 函数中就会调用它。 # 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
示例:通过cookie/session解决登录验证
------通过cookie/session解决登录验证
from django.shortcuts import redirect from django.shortcuts import render from login import models # 获取类才能orm操作库
from functools import wraps # 将装饰器的功能函数名还原 """ cookie与session解决登录验证 1、models中创建UserInfo类 python manage.py makemigrations login /migrate login --database=login_db 2、urls.py全局中配置app的urls url(r'^login/$', include('app_name.urls')) from django.conf.urls import url,include 3、在app下的views.py 创建视图函数 需求:登录除登录页面外,都需要登录才行!!! 思路: 1、用户打开页面,判断用户是否登录,已登录则直接打开,未登录则跳到登录页面登录 2、用户登录完成后,跳转到用户第一次访问时想要的页面 3、故实现上步需要提前获取用户要访问的页面url地址,保存下来 4、用户第一次登录时给用户配置一个cookie设置一个key:value保存状态同访问页面一起返回给浏览器 """ # 通过cookie解决登录验证 # 保存状态,服务器产生,让浏览器存放在浏览器端,一组组键值对,4096字节长度,不够大,不安全 # 校验登录装饰器 def check_login(func):
@wraps(func) def inner(request, *args, **kwargs): """获取用户想访问的url保存下来,判断cookie状态,确认用户是否登录""" print(request.path) return_url = request.path_info # 获取用户第一次访问的url,不含域名及参数 # if request.COOKIES.get('is_login', "") == 'True': # 获取cookie,比较值,如果符合,说明已经登录,跳转到用户需求页面 if request.session.get('is_login', "") == 'True': # session ret = func(request, *args, **kwargs) # 忘了写request参数,from表单里忘了{%csrf_token%} else: # 如何不符合跳转登录,且将用户想访问的url拼接到登录url后面,博客园就是这么做的 ret = redirect('/login/sigin/?ReturnUrl={}'.format(return_url)) return ret return inner def login(request): """验证用户,及配置cookie""" err_msg = "" if request.method == 'POST': username = request.POST.get('username').strip() password = request.POST.get('password').strip() # 获取前端传过来的用户名和密码 if not username or not password: err_msg = "用户名或密码不能为空" return render(request, 'app_login.html', {'err_msg': err_msg}) db_select = models.UserInfo.objects.filter(name=username, password=password) if db_select: # 如果正确的话,需要设置cookie相当于一个flag,设置cookie必须时response对象 return_url = request.GET.get('ReturnUrl', '/login/index/') # 获取用户要访问的页面,如果一开始就直接登录页面的话,成功后我们设置自动跳到index ret = redirect(return_url) # 跳转到用户未登录前要访问的页面 # ret.set_cookie('is_login', 'True') # 设置cookie以dict形式保存,请求后可以F12查看 request.session['is_login'] = 'True' # session return ret # 就跳到用户想的要的页面,否则回到登录页面 else: # 用户名密码错误的话,提示错误,还是返回登录页面 err_msg = '用户名或密码错误,请重新登录' return render(request, 'app_login.html', {'err_msg': err_msg}) @check_login def logout(request): # 退出就跳到登录页面 rep = redirect(to='/login/sigin/') # rep.delete_cookie('is_login') request.session.delete() # session的删除方法
del request.session['is_login'] return rep @check_login def index(request): return render(request, 'app_index.html') @check_login def home(request): return render(request, 'app_home.html')
思维亮点:如何让用户登录后跳转到用户需求的页面,什么时候获取需求url,怎么处理 # 问题? # 为什么post请求中可以通过return_url = request.GET.get('ReturnUrl', '/login/index/')
session与cookie的区别,为什么cookie是不安全的?
1、cookie数据存放在客户的浏览器上,session数据存放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑安全应当使用session。
3、session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、单个cookie保存的数不能超过4k,且cookie的个数也有限制,很多浏览器限制一个站点最多保存20个cookie。
注:建议
将登陆信息等重要信息存放session
其它信息如果需要保留,可以放在cookie中(存放在客户端)减轻服务端压力,提高网站的性能
禁止cookie的解决方案
cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时 仍然能够把session id传递回服务器。 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器 会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
<form name="testform" action="/xxx"> <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"> <input type="text"> </form>
实际上这种技术可以简单的用对action应用URL重写来代替。
一、cookie机制和session机制的区别 ************************************************************************************* 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。 同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session 机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择 ************************************************************************************* 二、会话cookie和持久cookie的区别 ************************************************************************************* 如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。 如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。 存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。 ************************************************************************************* 三、如何利用实现自动登录 ************************************************************************************* 当用户在某个网站注册后,就会收到一个惟一用户ID的cookie。客户后来重新连接时,这个 用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。 ************************************************************************************* 四、如何根据用户的爱好定制站点 ************************************************************************************* 网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。 ************************************************************************************* 五、cookie的发送 ************************************************************************************* 1.创建Cookie对象 2.设置最大时效 3.将Cookie放入到HTTP响应报头 如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上,则 需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。 发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP请求报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此我们将这个方法称为是addCookie,而非setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。 六、cookie的读取 ************************************************************************************* 1.调用request.getCookie 要获取有浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。 2.对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止 cookie与你的主机(域)相关,而非你的servlet或JSP页面。因而,尽管你的servlet可能只发送了单个cookie,你也可能会得到许多不相关的cookie。 例如: String cookieName = “userID”; Cookie cookies[] = request.getCookies(); if (cookies!=null){ for(int i=0;i<cookies.length;i++){ Cookie cookie = cookies[i]; if (cookieName.equals(cookie.getName())){ doSomethingWith(cookie.getValue()); } } } ************************************************************************************* 七、如何使用cookie检测初访者 ************************************************************************************* A.调用HttpServletRequest.getCookies()获取Cookie数组 B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确 C.如果是则退出循环并设置区别标识 D.根据区别标识判断用户是否为初访者从而进行不同的操作 ************************************************************************************* 八、使用cookie检测初访者的常见错误 ************************************************************************************* 不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null,客户可能是一个初访者,也可能是由于用户将cookie删除或禁用造成的结果。 但是,如果数组非null,也不过是显示客户曾经到过你的网站或域,并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及非Java Web应用都可以设置cookie,依据路径的设置,其中的任何cookie都有可能返回给用户的浏览器。 正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。 ************************************************************************************* 九、使用cookie属性的注意问题 ************************************************************************************* 属性是从服务器发送到浏览器的报头的一部分;但它们不属于由浏览器返回给服务器的报头。 因此除了名称和值之外,cookie属性只适用于从服务器输出到客户端的cookie;服务器端来自于浏览器的cookie并没有设置这些属性。 因而不要期望通过request.getCookies得到的cookie中可以使用这个属性。这意味着,你不能仅仅通过设置cookie的最大时效,发出它,在随后的输入数组中查找适当的cookie,读取它的值,修改它并将它存回Cookie,从而实现不断改变的cookie值。 ************************************************************************************* 十、如何使用cookie记录各个用户的访问计数 ************************************************************************************* 1.获取cookie数组中专门用于统计用户访问次数的cookie的值 2.将值转换成int型 3.将值加1并用原来的名称重新创建一个Cookie对象 4.重新设置最大时效 5.将新的cookie输出 ************************************************************************************* 十一、session在不同环境下的不同含义 ************************************************************************************* session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。 然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义。 session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。 ************************************************************************************* 十二、session的机制 ************************************************************************************* session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。 但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。 如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。 ************************************************************************************* 十三、保存session id的几种方式 ************************************************************************************* A.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。 B.由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。 ************************************************************************************* 十四、session什么时候被创建 ************************************************************************************* 一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。 ************************************************************************************* 十五、session何时被删除 ************************************************************************************* session在下列情况下被删除: A.程序调用HttpSession.invalidate() B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间 C.服务器进程被停止 再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。 ************************************************************************************* 十六、URL重写有什么缺点 ************************************************************************************* 对所有的URL使用URL重写,包括超链接,form的action,和重定向的URL。每个引用你的站点的URL,以及那些返回给用户的URL(即使通过间接手段,比如服务器重定向中的Location字段)都要添加额外的信息。 这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此,每个页面都必须使用servlet或JSP动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接再次回来,会话的信息都会丢失,因为存储下来的链接含有错误的标识信息-该URL后面的SESSION ID已经过期了。 ************************************************************************************* 十七、使用隐藏的表单域有什么缺点 ************************************************************************************* 仅当每个页面都是有表单提交而动态生成时,才能使用这种方法。单击常规的<A HREF..>超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程 ************************************************************************************* 十八、会话跟踪的基本步骤 ************************************************************************************* 1.访问与当前请求相关的会话对象 2.查找与会话相关的信息 3.存储会话信息 4.废弃会话数据 ************************************************************************************* 十九、getSession()/getSession(true)、getSession(false)的区别 ************************************************************************************* getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象 getSession(false):当session存在时返回该session,否则不会新建session,返回null ************************************************************************************* 二十、如何将信息于会话关联起来 ************************************************************************************* setAttribute会替换任何之前设定的值;如果想要在不提供任何代替的情况下移除某个值,则应使用removeAttribute。这个方法会触发所有实现了HttpSessionBindingListener接口的值的valueUnbound 方法。 ************************************************************************************* 二十一、会话属性的类型有什么限制吗 ************************************************************************************* 通常会话属性的类型只要是Object就可以了。除了null或基本类型,如int,double,boolean。 如果要使用基本类型的值作为属性,必须将其转换为相应的封装类对象 ************************************************************************************* 二十二、如何废弃会话数据 ************************************************************************************* A.只移除自己编写的servlet创建的数据: 调用removeAttribute(“key”)将指定键关联的值废弃 B.删除整个会话(在当前Web应用中): 调用invalidate,将整个会话废弃掉。这样做会丢失该用户的所有会话数据,而非仅仅由我们 servlet或JSP页面创建的会话数据 C.将用户从系统中注销并删除所有属于他(或她)的会话 调用logOut,将客户从Web服务器中注销,同时废弃所有与该用户相关联的会话(每个Web应用至多一个)。这个操作有可能影响到服务器上多个不同的Web应用 ************************************************************************************* 二十三、使用isNew来判断用户是否为新旧用户的错误做法 ************************************************************************************* public boolean isNew()方法如果会话尚未和客户程序(浏览器)发生任何联系,则这个方法返回true,这一般是因为会话是新建的,不是由输入的客户请求所引起的。 但如果isNew返回false,只不过是说明他之前曾经访问该Web应用,并不代表他们曾访问过我们的servlet或JSP页面。 因为session是与用户相关的,在用户之前访问的每一个页面都有可能创建了会话。因此isNew为false只能说用户之前访问过该Web应用,session可以是当前页面创建,也可能是由用户之前访问过的页面创建的。 正确的做法是判断某个session中是否存在某个特定的key且其value是否正确 ************************************************************************************* 二十四、Cookie的过期和Session的超时有什么区别 ************************************************************************************* 会话的超时由服务器来维护,它不同于Cookie的失效日期。首先,会话一般基于驻留内存的cookie 不是持续性的cookie,因而也就没有截至日期。即使截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。 ************************************************************************************* 二十五、session cookie和session对象的生命周期是一样的吗 ************************************************************************************* 当用户关闭了浏览器虽然session cookie已经消失,但session对象仍然保存在服务器端 ************************************************************************************* 二十六、是否只要关闭浏览器,session就消失了 ************************************************************************************* 程序一般都是在用户做log off的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭,因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。 之所以会有这种错误的认识,是因为大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接到服务器时也就无法找到原来的session。 如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的session id发送到服务器,则再次打开浏览器仍然能够找到原来的session。 恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。 由此我们可以得出如下结论: 关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。 ************************************************************************************* 二十七、打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session ************************************************************************************* 通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的session id,这样我们信息共享的目的就达不到了。 此时我们可以先把session id保存在persistent cookie中(通过设置session的最大有效时间),然后在新窗口中读出来,就可以得到上一个窗口的session id了,这样通过session cookie和persistent cookie的结合我们就可以实现了跨窗口的会话跟踪。 ************************************************************************************* 二十八、如何使用会话显示每个客户的访问次数 ************************************************************************************* 由于客户的访问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值 但像Integer是一种不可修改(Immutable)的数据结构:构建后就不能更改。这意味着每个请求都必须创建新的Integer对象,之后使用setAttribute来代替之前存在的老的属性的值。例如: HttpSession session = request.getSession(); SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”); if (value= =null){ value = new SomeImmutableClass(…); // 新创建一个不可更改对象 }else{ value = new SomeImmutableClass(calculatedFrom(value)); // 对value重新计算后创建新的对象 } session.setAttribute(“someIdentifier”,value); // 使用新创建的对象覆盖原来的老的对象 ************************************************************************************* 二十九、如何使用会话累计用户的数据 ************************************************************************************* 使用可变的数据结构,比如数组、List、Map或含有可写字段的应用程序专有的数据结构。通过这种方式,除非首次分配对象,否则不需要调用setAttribute。例如 HttpSession session = request.getSession(); SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”); if(value = = null){ value = new SomeMutableClass(…); session.setAttribute(“someIdentifier”,value); }else{ value.updateInternalAttribute(…); // 如果已经存在该对象则更新其属性而不需重新设置属性 } ************************************************************************************* 三十、不可更改对象和可更改对象在会话数据更新时的不同处理 ************************************************************************************* 不可更改对象因为一旦创建之后就不能更改,所以每次要修改会话中属性的值的时候,都需要 调用setAttribute(“someIdentifier”,newValue)来代替原有的属性的值,否则属性的值不会被更新 可更改对象因为其自身一般提供了修改自身属性的方法,所以每次要修改会话中属性的值的时 候,只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调 用setAttribute方法了 *************************************************************************************
Django中的session配置
Django中默认支持Session,其内部提供了5种类型的Session供开发者使用。
1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用设置项: 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,默认修改之后才保存(默认)