code学习

cookie、session、tooken

一、cookie 的诞生

首先需要知道Http协议的无状态连接的,即这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。

服务端,既不知道上一次请求和这一次请求的关联,也无法知道哪一个客户端来请求自己。

这时候,假设有一个客户请求了登录界面,然后登录成功,客户需要请求首页,由于http的无状态连接,不记得咱请求过登录,并且登录成功了,在首页就会看不到登录成功的用户信息。

【登录界面的用户信息无法共享给其他页面】

1、cookie 技术---客户端技术

为了解决http 无状态连接,导致无法共享数据的问题,然后像用户信息这种数据,明显就是好几个页面都需要用到的全局信息,每次请求都到数据库访问,会增大数据库的访问次数,同时导致减低访问速度;于是乎,cookie诞生了。

cookie把一些共享的信息(用户信息) 存储到客户端的浏览器,它在一个域名下是一个全局的。

2、cookie的不足

① cookie 存储的信息数量是有限制的,只能存储少量信息

② cookie 存储的信息在客户端的浏览器里,对于用户而言就是透明可见的,因为是在自己的浏览器上,所以用户就可以随意的修改,导致不安全

  • 假设如果真的cookie存储了用户的所有信息,那么像用户的密码这种东西在浏览器透明可见,太危险了。
将共享信息存储少量(不涉及安全问题的)信息存储到客户端浏览器,然后其他的信息(包括涉及用户安全的信息)存储到服务端,这种将共享信息(用户信息)存储到服务端的技术就是session技术。

二、session 的诞生

1、session 技术---服务端技术

session 其实也是特殊的cookie,只是信息存储的位置是在服务端。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

Session对象,保证一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话。

2、session 原理

是存储在服务端的一组数据。有些网站是采用session机制来验证用户身份的。Session对象主要是用来存储用户会话的数据。

SessionID需要存储在浏览器端,通常存储在 cookie 里。

浏览器发送接口请求的时候需要带着这个sessionID,服务器端就可以根据这个SessionID,找出当前请求的用户是谁了。

Session一般都会配置一个过期时间,Session过期之后,用户就需要重新登录了。

3、session 的不足

随着网站的用户越来越多,Session所需的空间会越来越大,同时单机部署的 Web应用会出现性能瓶颈。[​

​单机 session​

​​]

这时候需要进行架构的优化或调整,比如扩展Web 应用节点,在应用服务器节点之前实现负载均衡。[​

​分布式 session​

​]

负载均衡导致了session的管理出现了问题,难以保证一个用户的所有请求操作都应该属于同一个会话,会出现同一个用户请求应用A,在应用A的服务器上记录的用户信息[用户会话Session对象],然后该用户请求应用B,这时候,用于用户信息保存到A服务上,无法共享数据问题。

分布式会话的问题:

解决方式1:在负载均衡时,nginx 可以根据"hash_ip"算法将同一个 IP 的请求固定到某台服务器,这样来自于同一个 ip 的 session 请求总是请求到同样的服务器。

解决方式2:对session 进行剥离,把 session 数据彻底从业务服务器中剥离,单独存储在其他外部设备中(redis服务器--分布式缓存中间件)。且外部设备redis还可以采用主备或者主从,甚至集群的模式来达到高可用。、

4、cookie 和 session 的区别和选择:一般在项目中结合起来时候的

① cookie 数据存放在客户端上,session 数据放在服务器上。

② cookie 不安全,session 比较安全

③ session 保存在服务器上,当访问增多,会占用你服务器的性能,考虑到减轻服务器性能方面,应当使用 COOKIE。

session认证需要服务端做大量的工作来保证session信息的一致性以及session的存储,所以现代的web应用在认证的解决方案上更倾向于客户端方向,cookie认证是基于客户端方式的,但是cookie缺点也很明显。把认证信息保存在客户端,关键点就是安全的验证,session是一种方式。

如果只是针对用户登录这个应用场景,session 方案并不是唯一的解决方案---基于Token的认证

三、token 的诞生

目前市面上能见到的认证方式分为两大种——基于Session的和基于Token的。

基于Session的认证,是指在客户端存储一个Session Id。认证时,请求携带Session Id,并由服务器从Session数据存储中找到对应的Session。

基于Token的认证,是指将所有认证相关的信息在服务器端编码成一个Token(token 可以认为就是个长长的字符串),并由服务器签名,以确保不被篡改。Token本身是明文的。存在Token里的信息可以有比如user id、权限列表、用户昵称一类的。这样服务器只要拿着token和token的签名,就可以直接验证用户的身份是合法的。在现实当中,基于Token的认证的主要标准是Json Web Token (JWT)

1、token的引入---用户身份的验证

Token 是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token 便应运而生。

Token,直接就相当于一个身份证,给 Token 就能确定你的身份。

2、Token 的定义:

Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次带上用户名和密码。

最简单的 token 组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由 token 的前几位 + 盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接 token 请求服务器)。

● 当用户第一次使用账号密码成功进行登录后,服务器便生成一个Token及Token失效时间并将此返回给客户端,若成功登陆,以后客户端只需在有效时间内​

​带上这个Token前来请求数据即可,无需再次带上用户名和密码​

​。

3、使用 Token 的目的:

Token 的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

4、token验证

  • 每次服务器验证客户端请求里面带着的 Token,如果一开始服务端签发生成的token存储到数据库,那么后边的查询验证会很费时。如果不存储到数据库,应该存储到哪里呢?

    ---存储到内存中(使用redis缓存)

四、jwt~ 基于Token的认证的主要标准Json Web Token

由于现在的项目大多前后分离,api 跨域需求又那么多,api鉴权用jwt(使用jwt 来验证用户身份),因为jwt支持跨域使用,且因为有签名,所以JWT可以防止被篡改。

1、跨域session和cookie失效问题

由于跨域所以发送请求时不会带上cookie,而session是基于cookie的,所以cookie失效了session也会失效,那么怎么解决呢。

2、解决session和cookie失效问题

使用token来模拟session,将token放到请求头,前端每次请求都带上token,后端提供一个接口来给前端获取token。

token是遵从JWT规范的。

3、jwt官网两大用场景

  • Authorization(授权):这是 jwt 应用最为广泛的场景。jwt 将数据加密存储,分发给前端,前端将其放在特定的 header 字段中(也有放在 params 和 body 中),服务器收到请求后,解析 jwt 判断用户身份,对用户请求进行限权。
  • Information Exchange(数据交换): jwt 可以通过公钥和私钥对信息进行加密,双方通信后,互得数据。

4、jwt 有三部分组成:A.B.C

A:Header,{"type":"JWT","alg":"HS256"} 固定

B:playload,存放信息,比如用户id,过期时间等等,可以被解密,不能存放敏感信息

C: 签证,A和B加上秘钥 加密而成,只要秘钥不丢失,可以认为是安全的。

jwt 验证,主要就是验证C部分 是否合法。

☺ 五、面试聊聊cookie、session、token

这三个是不同维度的东西,没有什么可比性。

Cookie

是存储在浏览器的一小段文本数据;数据大小不超过4kb。Cookie的内容,会随着http请求一起发送到服务端,即发送网络请求的时候,cookie 会在请求头里一起发送给服务器端。

Session

是存储在服务端的一组数据。有些网站是采用session机制来验证用户身份的。Session对象主要是用来存储用户会话的数据。

SessionID需要存储在浏览器端,通常存储在 cookie 里。

浏览器发送接口请求的时候需要带着这个sessionID,服务器端就可以根据这个SessionID,找出当前请求的用户是谁了。

Session一般都会配置一个过期时间,Session过期之后,用户就需要重新登录了。

Token

在很多地方都会用到,是一个通用名词。通常用来表示一小段字符串。Token可以存储在cookie里,也可以存储到服务器的内存里,也可以存储到其他地方。Token 和session、cookie不是一个维度的东西。

目前有一种用户认证的机制,全名是json web token(jwt)。

参考文章:《Token ,Cookie 和 Session 的区别》​​https://jqiange.github.io/Token-,Cookie和Session的区别/​​