我是靠谱客的博主 温婉镜子,最近开发中收集的这篇文章主要介绍cookie与session说不清的纠缠,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近看到了一篇什么是单点登录(SSO)的文章,主要是讲述多个系统之间如何共享用户的登录状态,使之不需要重复登录。其中看见了自动登录,用到了session和cookie,查阅资料后,顺便把以前所学习的内容进行一次总结。

首先从代码使用上对cookie和session进行介绍:


cookie:
什么是cookie:cookie是保存在浏览器的一小块数据(一般浏览器保存cookie的个数的有上限的),它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。 下面首先说cookie的原理及使用:

核心API

  • 1.构造Cookie对象
    new Cookie(java.lang.String name, java.lang.String value)

  • 2.设置cookie
    void setPath(java.lang.String uri) :设置cookie的有效访问路径
    void setMaxAge(int expiry) : 设置cookie的有效时间
    void setValue(java.lang.String newValue) :设置cookie的值

  • 3.发送cookie到浏览器端保存
    void response.addCookie(Cookie cookie) : 发送cookie

  • 4.服务器接收cookie
    Cookie[] request.getCookies() : 接收cookie

Cookie原理

  • 1.服务器创建cookie对象,把会话数据存储到cookie对象中。
    new Cookie(“name”,“value”);

  • 2.服务器发送cookie信息到浏览器
    response.addCookie(cookie);
    举例: set-cookie: name=eric (隐藏发送了一个set-cookie名称的响应头)

  • 3.浏览器得到服务器发送的cookie,然后保存在浏览器端。

  • 4.浏览器在下次访问服务器时,会带着cookie信息
    举例: cookie: name=eric (隐藏带着一个叫cookie名称的请求头)

  • 5.服务器接收到浏览器带来的cookie信息
    request.getCookies();

Cookie细节

1)void setPath(java.lang.String uri)   :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。

2)void setMaxAge(int expiry) : 设置cookie的有效时间。
    正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
    负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
    零:表示删除同名的cookie数据  (在同一个路径下面)

3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

session:

session:session代表服务器与客户端的一次会话的过程。session对象存储用户指定的配置信息(存储在服务器端),这样在程序未结束前将会一直存在。当用户关闭会话或session超时而销毁。

核心API

  • 1)创建或得到session对象
    HttpSession getSession()
    HttpSession getSession(boolean create)

  • 2)设置session对象
    void setMaxInactiveInterval(int interval) : 设置session的有效时间
    void invalidate() : 销毁session对象
    java.lang.String getId() : 得到session编号

  • 3)保存会话数据到session对象
    void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
    java.lang.Object getAttribute(java.lang.String name) : 获取数据
    void removeAttribute(java.lang.String name) : 清除数据

session细节

  • 1)java.lang.String getId() : 得到session编号

  • 2)两个getSession方法:

    getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
    getSession(false): 得到session对象。没有匹配的session编号,返回null

  • 3)void setMaxInactiveInterval(int interval) : 设置session的有效时间
    session对象销毁时间:

    • 3.1 默认情况30分服务器自动回收
    • 3.2 修改session回收时间
    • 3.3 全局修改session有效时间

以上API方便快速开发时查询,下面对session和cookie的原理进行深度了解。(在查阅资料和查询dalao的博客总结)

问题一:cookie与session的异同

  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式的不同,Cookie 只能保存 字符串(以key-value形式),Session 可以存任意数据类型,一般情况下我们可以在 Session 中存储对象。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

问题二:下面引入为什么需要Cookie:

为什么需要引入cookie呢?由于浏览器与服务器交互是无状态的(HTTP协议无状态),这就意味着浏览器并不知道我是在和张三还是李四打交道,这时候需要一套标准来表示此次会话的谁和谁而这套标准就将cookie和session(下面介绍)的配合。

那么我们进一步思考,session与cookie是如何配合的呢?
session实现原理
图片来自网络,侵删

用户第一次请求服务器时,服务器创建session,响应客户端,将SessionID(session的唯一标识)返回浏览器。浏览器接收SessionID后,将此信息存储与cookie中。同时cookie记录sessionID属于哪个域名。
用户第二次请求服务器时,客户端请求是带着cookie去的,而服务器端从cookie中获取sessionID,查找对应的session信息,这样就可以达到效果—服务器端是在和谁打交道。

下面咱们从代码的角度去解读session
HttpSession session=request.getSession()

  • 1 第一次访问创建session对象,给session对象分配一个唯一的ID,叫做JSESSIONID。
    new HttpSession()
  • 2 把JSESSIONID作为cookie的值发送给浏览器。
    Cookie cookie=new Cookie(“JSESSIONID”,sessionID);
    response.addCookie(cookie);
  • 3 当客户端第二次访问服务端时,浏览器带着名字为JSESSIONID的cookie访问浏览器。
  • 4 服务器根据key为JSESSIONID找到对应的sessionID的值,在服务器内搜索是否存在放对应编号的session对象。
    if(找到){
    return map.get(sessionID);
    }
    猜想:底层可能是一个Map<String,HttpSession>存储的。
  • 5 如果找到对应的session对象,直接返回该对象。
  • 6 如果找不到对应编号的session对象,则重新创建一个新的session对象(从流程1开始)

注: JSESSIONID与sessionID的关系是,JSESSIONID是sessionID存放在cookie中的名字(cookie中的key值)
结论:通过Cookie的值在服务器中找session对象。

问题三:如何解决session共享呢?
在单系统下session可以在各个业务层获取到,但是在分布式系统下,往往将业务进行水平分割,也许登录功能单独作为一个系统,前端页面显示作为一个系统,广告页又单独作为一个系统等等。那么多系统下就需要解决session共享的问题。
下面总结一下dalao的解决办法:

  • Session 复制,任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。
  • 共享 Session,服务端无状态话,将用户的 Session 等信息使用缓存中间件来统一管理,保障分发到每一个服务器的响应结果都一致。
  • 把session数据放在redis中(使用redis模仿session)

最后

以上就是温婉镜子为你收集整理的cookie与session说不清的纠缠的全部内容,希望文章能够帮你解决cookie与session说不清的纠缠所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部