shiro(12)-session与token(有状态认证PK无状态认证)

shiro安全控制目录

在构建一个系统的时候,权限管理和用户认证是最基本的功能。而用户认证就是一个比较常见的模块。在已有的方案中,我们最常见的就是保存到tomcat的session对象中,而随着微服务的兴起,一种新的认证方式又火了起来,那就是JWT。

Sessionid和Token的区别

序 Session和Token的区别:

1. session出现的原因

因为http协议是无状态的,所以服务端不能判断本次请求和上次请求是不是同一个人操作的,故使用cookie和session来维护客户状态。

2. session生成的方式

浏览器在第一次访问服务器时,服务器创建一个session,然后同时为该session生成一个唯一的会话sessionId,然后将sessionId和session存储到Redis/内存中,然后服务器再把sessionId(名字为JESSIONID的cookie),以cookie形式发送给客户端。

浏览器再次访问时会携带cookie中的sessionId,然后服务器根据sessionId找到对应的session进行匹配。如果浏览器禁用了cookie/不支持cookie,可以通过URL重写的方式发送到服务器。

3. token出现的原因

session的存储是需要空间的,session的传输一般都是通过cookie来传输,或url重写的方式。而token在服务器时可以不存储用户信息的,token传递的方式也不限于cookie传递,token也可以保存起来。

4. token和session的区别

共同点:都是保存了用户身份信息,都有过期时间。
session是会话,而token是令牌。
session是空间换时间,token是时间换空间。
session和sessionId:服务器会保存一份,可能保存到缓存/数据库/文件。
token:服务器不需要记录任何东西,每次都是一个无状态的请求,每次都是通过解密算法来验证是否合法。
sessionId:一般是随机字符串,要到服务器检索id的有效性。

1. 两种认证方式的区别

当一个设备(客户端)向一个设备(服务端)发送请求的时候,服务端如何判断这个客户端是谁?传统意义上的认证方式又两种:有状态认证、无状态认证。有状态认证和无状态认证最大的区别就是服务器会不会保存客户端的信息。

2. 有状态认证

有状态认证,以cookie-session模型为例,当客户端第一次请求服务端的时候,服务端会返回客户端一个唯一的标识(默认在cookie中),并保存对应的客户端信息,客户端接受到唯一标识之后,将标识保存到本地cookie中,以后的每次请求都携带此cookie,服务器根据此cookie标识就可以判断请求的用户是谁,然后查到对应用户的信息。

shiro的有状态认证逻辑图.png

请求认证过程(以tomcat为例)

  1. 客户端向服务器发送请求;
  2. 第一次客户端发起请求,服务器创建一个key为SESSIONID的值,并写入到客户端的cookie中,同时在服务器的Session Manager中创建一个对象,保存这个JESSIONID对应的信息。
  3. 以后客户端每次请求,都会根据cookie进行区别,我们可以通过session.setAttribute,session.getAttribute等方法扩展用户信息,根据用户信息做一些业务判断。
  4. Session Manager中维护一个定时器,当SESSIONID对应的信息长时间没有访问(默认30分钟),或者显式调用session.invalidate方法,那么这个对应的信息就会被删除。

SESSION认证优势

因为客户端信息都保存在服务器的Session Manager中,如果将客户端的认证信息取消,只需要将Session中对应信息删除即可,及时相应,方便快捷。

SESSION认证劣势

本质上是以空间换时间。

  1. 因为服务端保存着客户端的信息,当用户量特别多时候,服务端需要特别的内存资源;
  2. 如果失效时间特别长的情况下,大量资源被占用无法释放,如果释放,那么相当于用户的注销登录;
  3. 客户端的信息在服务端中维护,如果服务端为集群的场景下,那么客户端信息不共享,必须使用分布式 session 或者其他方案;
  4. cookie有同源策略和跨域限制,部分业务场景下cookie并不能传递;
  5. 部分设备本身不支持cookie或者禁用cookie,还有的手机浏览器也不支持cookie。

Shiro有状态身份认证——会话管理(整合Redis实现共享Session)

3. 无状态认证

无状态的认知,客户端在提交身份信息,服务端验证身份后,根据一定的算法生成一个token令牌返回给客户端,之后每次请求服务端,客户端都需要携带此令牌,服务器接受到令牌之后进行校验,校验通过后,提取令牌的信息用来区别用户。

无状态认证.png

请求认知过程

  1. 执行登录操作,用户端发送账号密码等信息。
  2. 服务端校验账号密码是否正确,如果正确,根据对应的用户信息和服务端秘钥生成JWT令牌,然后通过response.setHeader返回给客户端(此处假设生成一个名为x-auth-token的令牌)。
  3. 客户端在返回成功之后,将Header中的x-auth-token保存到本地中。
  4. 客户端在以后每次请求服务器的时候,都会在header中携带x-auth-token令牌的值。
  5. 服务端每接受到请求之后,判断hader中是否包含x-auth-token,token 是否有效,然后通过 BASE 64 算法 decode,根据解密后的参数,判断当前 token 是否在有效期,所访问的接口是否有权限等操作。

优势

  1. 因为服务器不保留客户端的任何信息,每次只需要通过特定的算法进行校验,节省了大量的存储空间。
  2. 方便水平扩容,不需要 SSO Server,只要保证新的应用采用同样的验证算法,就可以验证通过并获得对应信息。

劣势

本质上是以时间换空间
当客户端的token被盗用,或者需要手动封禁某个用户的时候,没办法对此token进行操作,必须等待token失效(如果在服务端维护token和用户的关系,技术可以实现,但是违背无状态的设计理念)。

本文参考:

史亚健——浅析权限认证中的有状态和无状态

你可能感兴趣的:(shiro(12)-session与token(有状态认证PK无状态认证))