彻底理解Session、Cookie、Token,入门及实战

news/2024/11/29 2:30:39/

文章目录

  • Session + Cookie的使用
  • Token的使用

Session + Cookie的使用

1. Session存储数据

HttpSession session = request.getSession();			//Servlet底层通过的SESSIONID,获取Session对象。
session.setAttribute("loginTime",new Date());
out.println("登录时间为:"+(Date) session.getAttribute("loginTime"));
- void setAttribute(String attribute,Object value):			设置Session属性。value信息不宜过大
- String getAttribute(String attribute):						返回Session属性
- Enumeration getAttributeNames():							返回Session中存在的属性名
- void removeAttribute(String attribute):					移除Session属性
- String getId():											返回Session的ID
- long getCreationTime():									返回Session的创建日期
- long getLastAccessedTime():								返回Session的最后活跃时间
- int getMaxInactiveInterval():								返回Session的超时时间
- int setMaxInactiveInterval(int second):					设置Session的超时时间
- boolean isNew():											返回该Session是否新创建的
- void invalidate():											使Session失效

2. Cookie存储数据

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie
cookie.setMaxAge(0);                          // 设置生命周期为0,不能为负数
response.addCookie(cookie);                    // 必须执行这一句

在这里插入图片描述

3. Session + Cookie 的区别

  • 生存周期:Session从IE启动到IE关闭.,Cookie是用户可以预先设置的生存周期。
  • 存储地方:Session数据放在服务器上,Cookie数据存放在客户的浏览器中

4. Session + Cookie的配合使用
我们知道了 Cookie 由于存储的内存空间只有 4kb,因此存储的主要是一个用户 id,其他的用户信息都存储在服务器的 Session

  1. 服务器接收到请求后,通过request.getSession()方法创建会话对象。此方法第一次调用是创建session会话,以后在session没有被销毁前,再次调用都是获取前面创建的session。
  2. 服务器在每次创建session的时候,也会创建cookie,这个cookie的key永远是JESSIONID。value是创建的session的id。
  3. 通过响应将新创建的session的id,放在cookie里,传给浏览器。Set-Cookie:JESSIONID=XXX
  4. 浏览器解析获取到的数据,就马上创建一个cookie对象。有了cookie之后,再次请求服务器,就会把含有session的id的cookie,传给服务器Cookie:JESSIONID=XXX
  5. 服务器通过request.getSession方法,通过cookie里面的session的id,找到之前创建好的session对象,返回相应的数据。

在这里插入图片描述

Token的使用

1. Token出现原因
通过Session + Cookies将数据存储在服务器中,当用户数量急剧时,服务器需要耗费大量的sessionId。这显然对服务器说是一个巨大的开销,这就使用到了Token。

2. Token的结构
头部(header)
Token头部承载两部分信息:声明类型、声明加密算法

{ 
"typ": "JWT",
"alg": "HS256"
}

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

载荷(payload)
有效信息包含三个部分:标准中注册的声明、公共的声明、私有的声明。

1. 标准中注册的声明 (建议但不强制使用)

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

2. 公共的声明

  • 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密

3. 私有的声明

  • 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload

{    
"uid":"e12a34b56c78d9e0f",
"name":"ramostear",
"role":"admin"
}

然后将其进行base64加密

eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9

签证(signature)
这个部分需要base64加密后的header和base64加密后的payload,连接组成的字符串,然后通过header中声明的加密方式进行secret密钥组合加密,然后就构成了第三部分:

49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY

3. Token如何生成
Token怎么制作呢

  1. 将荷载payload,Header信息进行Base64加密,形成payload密文,header密文。
  2. 将形成的密文用句号链接起来,用服务端秘钥进行HS256加密,生成签名.
  3. 将前面的两个密文后面用句号链接签名形成最终的token返回给服务端
    在这里插入图片描述
    服务器如何检验
  1. 服务端使用原来的秘钥与密文(header密文+“.”+payload密文)同样进行HS256运算,然后用生成的签名与token携带的签名进行对比,若一致说明token合法,不一致说明原文被修改。
  2. 判断是否过期,客户端通过用Base64解密第二部分(payload密文),可以知道荷载中授权时间,以及有效期。通过这个与当前时间对比发现token是否过期。

4. Token的C/S交互

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端,客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage
  4. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token,服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
  5. APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时,凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。

5. Token与Cookie的区别

  • 内存空间:Cookie 由于存储的内存空间只有 4kb,因此存储的主要是一个用户 id,其他的用户信息都存储在服务器的 Session 中,而 Token 没有内存限制,用户信息可以存储 Token 中,返回给用户自行存储,因此可以看出,采用 Cookie 的话,由于所有用户都需要在服务器的 Session 中存储相对应的用户信息,所以如果用户量非常大,这对于服务器来说,将是非常大的性能压力,而Token 将用户信息返回给客户端各自存储,也就完全避开这个问题了。

6. Token与Cookie的联系
客户端将Token存储到Cookie中,可以设置token的有效时间

7. Token的定制化生成
生成Token
主要是填充载荷部分

// 生成token方法
public String generateToken(Map<String, Object> claims) { returnJwts.builder().setClaims(claims)		//设置载荷.setExpiration(generateExpirationDate())	//设置过期时间.signWith(SignatureAlgorithm.forName(alg), secret)	//设置签名.compact();
}

获取Token

/** * 获得token内的内容 * @param token * @return */
public Claims getClaimsFromToken(String token) { try { Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();} catch (Exception e) { claims = new DefaultClaims();log.warn("{}", e.getMessage(), e);}return claims;
}

http://www.ppmy.cn/news/32683.html

相关文章

ChatGPT新进展GPT-4 模型介绍

文章目录背景工具功能使用增强背景 2023.3.14 GPT-4 模型发布 创建了GPT-4&#xff0c;这是OpenAI在扩大深度学习方面的最新里程碑。GPT-4是一个大型多模态模型(接受图像和文本输入&#xff0c;输出文本输出)&#xff0c;虽然在许多现实场景中不如人类&#xff0c;但在各种专业…

Unity AR应用(人脸识别)手把手教程

Unity官方有个教程&#xff0c;照着一步一步操作&#xff0c;就能做出一个典型的AR应用&#xff1a;人脸识别虚拟穿戴。其实&#xff0c;人脸识别和跟踪都是设备平台实现的功能&#xff08;如Android的ARCore或iOS的ARKit&#xff09;&#xff0c;在Unity里只是进行配置工作。真…

RK3568平台开发系列讲解(网络篇)使用socket建立TCP连接

文章目录 一、服务端1.1、socket: 创建套接字1.2、bind: 设定电话号码1.3、listen: 接上电话线,一切准备就绪1.4、accept: 电话铃响起了二、客户端三、TCP 三次握手🚀返回专栏总目录 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将分别从服务端和客户端的…

计算机网络的基本组成

计算机网络是由多个计算机、服务器、网络设备&#xff08;如路由器、交换机、集线器等&#xff09;通过各种通信线路&#xff08;如有线、无线、光纤等&#xff09;和协议&#xff08;如TCP/IP、HTTP、FTP等&#xff09;互相连接组成的复杂系统&#xff0c;它们能够在物理层、数…

普通Java工程师 VS 优秀架构师

1 核心能力 1.1 要成为一名优秀的Java架构师 只懂技术还远远不够&#xff0c;懂技术/懂业务/懂管理的综合型人才&#xff0c;才是技术团队中的绝对核心。 不仅仅是架构师&#xff0c;所有的技术高端岗位&#xff0c;对人才的综合能力都有较高的标准。 架构路线的总设计师 规…

朋友去华为面试,轻松拿到26K的Offer,羡慕了......

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

ChatGPT-4震撼发布

3月15日消息&#xff0c;美国当地时间周二&#xff0c;人工智能研究公司OpenAI发布了其下一代大型语言模型GPT-4&#xff0c;这是其支持ChatGPT和新必应等应用程序的最新AI大型语言模型。该公司表示&#xff0c;该模型在许多专业测试中的表现超出了“人类水平”。GPT-4, 相较于…

chrome快捷键

Ctrl T&#xff1a;打开新标签页。Ctrl W&#xff1a;关闭当前标签页。Ctrl Shift T&#xff1a;重新打开最近关闭的标签页。Ctrl Tab&#xff1a;在打开的标签页之间切换。Ctrl Shift Tab&#xff1a;在打开的标签页之间反向切换。Ctrl N&#xff1a;打开新窗口。Ctrl…