Session、Cookie和Token的简介、技术核心和实现原理

Cookie 、Session 、Token

HTTP 协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。

1、Cookie

1.1、cookie 简介

HTTP 协议中的 Cookie 包括 Web Cookie浏览器 Cookie,它是服务器发送到 Web 浏览器的一小块数据。服务器发送到浏览器的 Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。

1.2、Cookie 核心技术

Cookie技术:会话数据保存在浏览器客户端。

Cookie类:用于存储会话数据

​ 1.构造Cookie对象

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的值

  1. 发送cookie到浏览器端保存

void response.addCookie(Cookie cookie) : 发送cookie

​ 4.服务器接收cookie

Cookie[] request.getCookies() : 接收cookie

1.3、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();

1.4、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。

//案例- 显示用户上次访问的时间
@WebServlet("/LastAccessTime")
public class LastAccessTime extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf-8");// 防止浏览器显示乱码
		String lastAccessTime = null;
        //服务器接收来自游览器的cookie
		Cookie[] cookies = req.getCookies();
		for (Cookie cookie : cookies) {
			String name = cookie.getName();
			if (name.equals("lastAccessTime")) {
				lastAccessTime = cookie.getValue();
				break;
			}
		}
		if (StringUtils.isEmpty(lastAccessTime)) {
			resp.getWriter().print("您是首次访问!");
		} else {
			resp.getWriter().print("你上次访问时间:" + lastAccessTime);
		}
		// 保存访问时间
		// 创建cookie 将当前时间作为cookie保存到浏览器
		String currenttime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
        //创建Cookie对象
		Cookie cookie = new Cookie("lastAccessTime", currenttime);
        //设置cookie的有效时间
		cookie.setMaxAge(60 * 60 * 24);
		// 发送cookie到游览器
		resp.addCookie(cookie);

	}

	String addCookie(String key, String value, HttpServletResponse resp) {
		return key;
	}

}

2、Session

2.1、session 简介

客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是 Session 对象,存储结构为 ConcurrentHashMap。Session 弥补了 HTTP 无状态特性,服务器可以利用 Session 存储客户端在同一个会话期间的一些操作记录。

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的数据创建一个其独享的Session对象,由于Session为用户浏览器独享,所以当用户在访问服务器的web资源时,可以把各自的数据放在各自的Session中,当用户再去访问服务器中的其他的web资源的时候,其他的web资源再从用户各自的Session中取出数据为用户服务。

2.2、Session 引入

Cookie的局限:

​ 1)Cookie只能存字符串类型。不能保存对象

​ 2)只能存非中文。

​ 3)1个Cookie的容量不超过4KB。

如果要保存非字符串,超过4kb内容,只能使用session技术!!!

Session特点:会话数据保存在服务器端。(内存中)

2.3、session 缺点

Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。

2.4、session 技术核心

HttpSession类:用于保存回话数据

1.创建或得到session对象

HttpSession getSession() 直接创建一个session对象

HttpSession getSession(boolean create) 接收布尔值,设置为true,没有匹配的session编号,自动创建新的session对象;设置为false,没有匹配的session编号,返回为null

2.设置session对象

void setMaxInactiveInterval(int interval) : 设置session的有效时间

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

void invalidate() : 销毁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) : 清除数据

2.5、session 原理

问题: 服务器能够识别不同的浏览者!!!

前提: 在哪个session域对象保存数据,就必须从哪个域对象取出!!!!

​ 浏览器1:(给s1分配一个唯一的标记:s001,把s001发送给浏览器)

​ 1)创建session对象,保存会话数据

HttpSession session = request.getSession(); //保存会话数据 s1

​ 浏览器1 的新窗口(带着s001的标记到服务器查询,s001–>s1,返回s1)

​ 1)得到session对象的会话数据

HttpSession session = request.getSession(); //可以取出 s1

​ 新的浏览器1:(没有带s001,不能返回s1)

​ 1)得到session对象的会话数据

HttpSession session = request.getSession(); //不可以取出 s2

​ 浏览器2:(没有带s001,不能返回s1)

​ 1)得到session对象的会话数据

HttpSession session = request.getSession(); //不可以取出 s3

代码解读:HttpSession session = request.getSession();

1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID

new HttpSession();

2)把JSESSIONID作为Cookie的值发给游览器保存

Cookiecookie = new Cookie("JSESSIONID",sessionID);

request.addCookie(cookie);

3)第二次访问时,游览器带着JSESSIONID的cookie访问服务器

4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象

if(找到){
	return map.get(sessionID);
}
Map<String,HttpSession>
<"s001", s1>
<"s001,"s2>

5)如果找到对应编号的session对象,直接返回该对象

6)如果找不到对应编号的session对象,创建session对象,继续走 1)流程

结论:通过JSESSIONID的cookie值在服务器找session对象

2.6、session 细节

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

2)两个getSession方法

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

getSession(false) :得到session对象,没有匹配的session编号,返回null

3)void serMaxInactiveInterval(int interval) :设置session的有效时间

​ session对象销毁时间:

​ 3.1 默认情况30分钟服务器自动回收

​ 3.2 修改session回收时间

​ 3.3 全局修改session有效时间

session.setMaxInactiveInterval(30 * 60);

<!-- 修改session全局有效时间:分钟 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>

​ 3.4 手动销毁session对象

​ void invalidate() : 销毁session对象

4)如何避免游览器的JSESSION的cookie随游览器关闭而丢失问题

		/**
​		 * 手动发送一个硬盘保存的cookie给浏览器
​		 */Cookie c = ***\*new\**** Cookie("JSESSIONID",session.getId());
​		c.setMaxAge(60*60);
​		response.addCookie(c);

Cookie和Session总结

1)会话:游览器和服务器之间的数据传输

2)会话管理:游览器和服务器会话过程中产生的会话数据的管理

3)Cookie技术:

new Cookie("name","value")

response.addCookie(coookie)

request.getCookies()

4)Session技术:

request.getSession();

setAttrbute("name","会话数据");

getAttribute("会话数据")

3、token

3.1、token简介

令牌,是用户身份的验证方式。 最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)。

在对接一些第三方平台的时候,为了能够保证数据安全性,通常会使用一些令牌进行交互

3.2、token定义

token生成规则,只要保证token生成一个不重复的唯一字符串即可。

使用jdk自带的uuid生成规则。

3.3、UUID是什么

UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织应用在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部分。

UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。
在这样的情况下,就不需考虑数据库建立时的名称重复问题。目前最广泛应用的 UUID,即是微软的 Microsoft’s Globally Unique Identifiers (GUIDs),而其他重要的应用,
则有 Linux ext2/ext3 档案系统、LUKS 加密分割区、GNOME、KDE、Mac OS X 等等

  • 一个Token就是一些信息的集合;
  • 在Token中包含足够多的信息,以便在后续请求中减少查询数据库的几率;
  • 服务端需要对cookie和HTTP Authrorization Header进行Token信息的检查;
  • 基于上一点,你可以用一套token认证代码来面对浏览器类客户端和非浏览器类客户端;
  • 因为token是被签名的,所以我们可以认为一个可以解码认证通过的token是由我们系统发放的,其中带的信息是合法有效的;

3.4、UUID组成

UUID保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。
UUID由以下几部分的组合:
(1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
(2)时钟序列。
(3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12);

3.5、UUID代码

public class UuidUtil {

   public static String get32UUID() {
      String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
      return uuid;
   }
}
 
public final class UUID implements java.io.Serializable, Comparable<UUID> {
     public static UUID randomUUID() {
        SecureRandom ng = Holder.numberGenerator;

        byte[] randomBytes = new byte[16];
        ng.nextBytes(randomBytes);
        randomBytes[6]  &= 0x0f;  /* clear version        */
        randomBytes[6]  |= 0x40;  /* set to version 4     */
        randomBytes[8]  &= 0x3f;  /* clear variant        */
        randomBytes[8]  |= 0x80;  /* set to IETF variant  */
        return new UUID(randomBytes);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SessionCookieToken是常用于Web应用中的身份验证和状态管理的机制,它们有以下区别: 1. Session(会话):Session是一种服务器端的状态管理机制。当用户第一次访问网站时,服务器会为该用户创建一个唯一的Session ID,并将该ID存储在Cookie中发送给客户端。客户端在后续的请求中通过Cookie中的Session ID来标识自己。服务器根据Session ID来查找对应的会话数据,从而实现用户状态的管理。 2. Cookie(HTTP Cookie):Cookie是一种客户端的状态管理机制。服务器在响应中通过Set-Cookie头部将一些数据存储在客户端,客户端在后续的请求中通过Cookie头部将这些数据发送给服务器服务器根据Cookie中的数据来识别用户并进行相应的处理。 3. Token(令牌):Token是一种无的身份验证机制。当用户登录成功后,服务器会一个Token并返回给客户端。客户端在后续的请求中通过在请求头或参数中携带Token来进行身份验证。服务器通过验证Token的有效性来确定用户身份。 区别: - 存储位置:SessionToken存储在服务器端,而Cookie存储在客户端。 - 数据安全性:Token相对较安全,因为它可以使用加密算法进行签名和验证;而Cookie可以被窃取或篡改。 - 扩展性:Token可以用于多个应用程序,而Cookie只能在同一域名下共享。 - 状态管理:SessionCookie可以用于管理用户的状态信息,而Token主要用于身份验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值