Servlet - Sessions and Cookies

1. What

1.1 Session定义

Session对象是存储在服务器端的,主要用来存储用户会话所需的属性数据和配置数据。SessionlD需要存储在浏览器端,浏览器发送接口请求的时候需要带着这个SessionlD。一个会话就是用户通过浏览器与服务器之间进行的一次通话。

session的工作原理:

  • 服务器程序运行的过程中产生session,并且为该session生成唯一的session ID
  • 服务器将session ID发送给客户端
  • 客户端再次发送请求时,会将这个session ID带上
  • 服务器接收到请求之后,根据session ID找到相应的session,完成请求响应。

Session失效:

  • 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。
  • 调用Session的invalidate方法。

1.2 Cookie定义

Cookie是一小段存储在浏览器端的文本数据,大小不超过4KB。
key-value的数据:
name:cookie的名称
value:cookie的值

max-age:生存周期,max-age用秒来设置cookie的生存期

  • max-age属性为正数,则表示该cookie会在max-age秒之后自动失效
  • max-age为负数,则表示该cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该cookie即失效。
  • max-age为0,则表示删除该cookie

domain :Cookie 所属的域
path:Cookie 来源的网址路径
secure: 该Cookie是否仅被使用于安全协议传输。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。
httponly: 指示 Cookie 应仅由浏览器在 HTTP 请求中设置,而无法通过 JavaScript 访问。

2. Why

HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享。

3. How

Cookie和Session的比较:

比较因素CookiesSession
存储方式Cookie只能存储字符串,如果非要存储ASCII字符串还要对其编码Session可以存储任何类型的数据,可以把Session看出一个容器
隐私安全Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题
有效期Cookie保存在硬盘中,只需要设置magAge属性来控制,即使关闭浏览器,Cookie还是存在的Session保存在服务器中,设置maxlnactiveInterval属性来确定有效期。(如果使用Cookie的方式跟踪会话,Session依赖JessionID的Cookie,如果设置该Cookie的maxAge为-1,当关闭浏览器,该Session虽然没有从服务器中消亡,但是也还是失效的)
服务器的负担Cookie保存在客户端,不占用服务器资源。(baidu,Sina这样的大型网站一般使用Cookie来进行会话跟踪Session保存在服务器中,每个用户都会产生一个Session,如果并发访问的用户非常多,Session会消耗大量的内存
有浏览器支持如果浏览器禁用了Cookie,那Cookie就无用了如果浏览器禁用了Cookie,Session可以通过url地址重写进行会话跟踪
跨域名Cookie可以设置Domain属性来实现跨域名Session只在当前的域名内有效,不可跨域名
储存大小Cookie最多可以放4K大小的内容Session大小没有限制

4. Samples

4.1 Cookie的基本使用

  • 发送Cookie
    创建Cookie对象,设置数据: Cookie cookie =new Cookie(“key”,“value”);
    发送到Cookie客户端:使用response对象:response.addCookie(cookie);
  • 获取Cookie
    获取客户端携带的所有Cookie,使用request对象:Cookie[] cookie =request.getCookies();
    遍历数组,获取每一个Cookie对象:for
    使用Cookie对象方法获取数据 cookie.getName();
  • Cookie存储中文
    Cookie默认不能存储中文,如需要存储,可以进行URL转码

4.2 Session的基本使用

  • 获取Session对象:HttpSession session =request.getSession();
  • 存储Session对象功能
    void setAttribute(String name,Object o): 存储数据到session域中
    Object getAttribute(String name ): 根据key,获取值
    void removeAttribute(String name): 根据key,删除该键值对

4.3 实现会话跟踪的技术

4.3.1 Cookie

Cookie 是信息的键值对,由服务器发送到浏览器,然后浏览器将这个标识符连同那里的每个请求一起发送回服务器。
缺点:用户可以在浏览器中禁用 cookie 支持,在这种情况下服务器将无法识别用户,因此这是这种方法的主要缺点。

4.3.2 隐藏表单域

信息通过隐藏的表单字段插入网页,然后传输到服务器。这些字段对用户的视图是隐藏的。例如
<input type=”hidden” name=”sessionId” value=”unique value”/>
缺点:由于我们不能硬编码为会话跟踪目的而创建的隐藏字段的值,这意味着我们不能将这种方法用于HTML等静态页面

4.3.3 URL 重写

URL重写是在每个请求 URL 中附加一个会话(唯一)标识符以便服务器可以识别用户会话的方法。
例如:
如果我们在 http://localhost:8080/HelloWorld/SourceServlet 上应用URL重写,它将变成类似
http://localhost:8080/HelloWorld/SourceServlet?jSessionId=XYZ
其中 jSessionId=XYZ 是附加的会话标识符,服务器将使用值 XYZ 来识别用户会话。
优点:独立于浏览器,即使浏览器不支持Cookie,也可以实现功能
缺点:我们需要重新生成每个url以附加会话标识符,并且需要跟踪该标识符直到会话完成。

4.3.4 会话跟踪API

Servlet 使用 HttpSession API提供了一个方便且稳定的会话跟踪解决方案。

servlet 中的会话跟踪非常简单,包括以下步骤:

  • 使用request.getSession()获取关联的会话对象 (HttpSession ) 。
  • 要从会话对象中获取特定值,请在 HttpSession 对象上调用getAttribute(String) 。
  • 将任何信息存储在会话对象上的会话调用 setAttribute(key,object) 中。
  • 要删除会话数据,请调用 removeAttribute(key) 以丢弃具有给定键的对象。
  • 要使会话无效,请在会话对象上调用 invalidate()。这用于注销已登录的用户。

4.4 利用Session防止表单重复提交

服务器返回表单页面时,会先生成一个subToken保存于session,并把该subToen传给表单页面。当表单提交时会带上subToken,服务器拦截器Interceptor会拦截该请求,拦截器判断session保存的subToken和表单提交subToken是否一致。若不一致或session的subToken为空或表单未携带subToken则不通过。
首次提交表单时session的subToken与表单携带的subToken一致走正常流程,然后拦截器内会删除session保存的subToken。当再次提交表单时由于session的subToken为空则不通过。从而实现了防止表单重复提交。

4.5 微服务分布式session共享解决方案

4.5.1 基于tomcat的session共享(通常不采用)

优点:不需要额外开发,只需要搭建tomcat集权即可
缺点:tomcat是全局session复制,集群内每个tomcat的session完全同步,在大规模应用的时候,用户过多,集群内tomcat数量过多,session的全局复制会导致集群性能下降,而且依赖tomcat容器移植性不好。

4.5.2 cookie同步session,如JWT(json web token)

这种方式就是把客户信息保存在客户端的cookie中,每次请求带着cookie中的token
优点:由于完全舍弃了session,会减轻服务器端的压力
缺点:把客户信息暴露在外,存在安全性问题,当浏览器禁用cookie的情况下无效

4.5.3 redis集中管理session(常用)

优点:redis 为内存数据库,读写效率高,并可在集群环境下做高可用

4.5.4 基于Nginx的ip_hash负载均衡

其实就是对请求过来的ip地址对你的多少台可用的服务器进行取模,然后就会把你的请求通过Nginx的反向代理给分发到对应的服务器上。(这里会把可用的服务器放到一个数组中,如果取模得到的结果是几,就把请求分到服务器数组中的下标为几的服务器上)。
优点:配置简单,不需要修改代码。便于服务器水平扩展。安全性较高。
缺点:服务器重启会造成部分session丢失。水平扩展也会造成session丢失。存在单点负载较高的风险。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是王小贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值