Shiro(十)Session

553 阅读5分钟

介绍

Shiro中的Session管理是Shiro框架的一个核心组件,用于管理用户会话信息。Shiro的Session管理包括会话创建、销毁、过期等功能以及session存储策略,Shiro已经提供了完整的企业级Session管理。

Shiro的Session管理提供了以下的主要功能:

  1. 会话创建:当用户登录时,Shiro会创建一个会话并保存到会话存储中。用户在访问有权限控制的资源时,Shiro会检查会话是否存在,如果不存在则会创建一个新的会话。

  2. 会话过期:Shiro会自动检查会话是否过期。当会话过期时,Shiro会自动将会话标记为无效并从存储中移除。

  3. 退出登录和会话终止:当用户退出登录或关闭浏览器时,Shiro会自动将会话标记为无效并从存储中移除。

  4. Session的存储策略:Shiro提供了多种Session的存储策略,默认情况下,Shiro使用内存存储,但在实际生产环境中,往往使用更为安全的分布式缓存存储(如Redis、Memcached).

在Shiro中,可以通过以下的几种方式进行Session管理:

  1. 内存存储:所有的Session信息都会保存在内存中。这种方式在开发调试时使用比较方便,但在高并发、分布式环境下不够稳定。

  2. Cookie 存储:将Session信息保存在Cookie中。当用户请求资源时,Shiro会解析Cookie中的Session信息并进行验证。这种方式简便,但不够安全和可靠。

  3. URL 重写:将Session ID 保存在URL中,通过 URL 分发给浏览器端。在访问资源时,浏览器会自动发送URL中包含的Session ID,Shiro会解析并进行验证。但是这种方式存在泄漏 Session ID 的风险。

  4. 缓存存储:将Session信息保存在缓存中,如 Redis、Memcached等。这种方式在高并发、分布式环境下较为稳定和可靠。

总的来说,Shiro提供了多种Session管理的方式。在实际开发中,需要根据站点访问的环境进行选择,根据安全需求进行选择。如果站点用户量不大,则可以使用内存存储;如果站点有高访问量或者并发量,则应该使用缓存存储或另外的分布式存储。

使用

登录成功后使用 Subject.getSession() 即可获取会话;其等价于 Subject.getSession(true),即如果当前没有创建 Session 对象会创建一个;另外 Subject.getSession(false),如果当前没有创建 Session 则返回 null(不过默认情况下如果启用会话存储功能的话在创建 Subject 时会主动创建一个 Session)

@RestController 
public class HelloController { 
@Autowired private Subject subject; 
@GetMapping("/hello") 
public String sayHello() {
// 获取当前Session对象 
Session session = subject.getSession();
// 设置Session属性 
session.setAttribute("user", "testuser"); 
// 获取Session属性 
String user = (String) session.getAttribute("user"); 
return "Hello " + user; 
} }

API

Shiro提供的其他的SessionAPI

  1. getSession:获取当前请求的Session对象,如果当前请求中没有Session,则创建一个新的Session。

  2. setAttribute:设置Session属性,通过Key-Value的形式来实现存储。

  3. getAttribute:获取Session属性,通过Key获取对应的Value。

  4. removeAttribute:移除Session中存储的某个属性。

  5. getId:获取Session ID,在会话过程中,Session ID是唯一的标识。

  6. getCreationTime:获取Session创建时间。

  7. getLastAccessTime:获取Session最后访问时间。

  8. getTimeout:获取Session过期时间。如果Session在这个时间内没有操作,则认为Session过期。

  9. setTimeout:设置Session的过期时间。

  10. invalidate:使当前Session失效。

使用以上API,可以实现在程序中对Session的有效操作,例如设置Session属性,在多个页面之间共享信息等。同时也可以通过获取Session ID、过期时间等信息,实现对Session的有效管理,提高应用程序的安全性和可靠性。

在实际应用中,Shiro还提供了更为全面和灵活的Session实现方案,例如基于Cookie的Session管理和基于集中式缓存的Session管理等,可以有效地解决Session过期失效、Session验证等问题,有兴趣的大家可以自己查询。

原理及继承体系

Shiro的Session是用来存储用户状态信息的,在Shiro中,Session是从Subject中获取的,Subject是代表当前用户的抽象。Shiro Session提供了会话管理的功能,包括会话创建、销毁、过期、续期等。下面是Shiro中Session会话管理的实现和继承体系:

  1. org.apache.shiro.session.Session 接口:Session接口是Shiro Session的基本接口,定义了Session的基本属性和操作方法,包括获取Session ID、获取、设置Session属性、获取过期时间、判断是否过期、设置过期时间、退出登录等方法。

  2. org.apache.shiro.session.mgt.SessionManager 接口:SessionManager是Shiro Session管理器的接口,可以创建Session、获取Session、销毁Session、验证Session等管理操作。

  3. org.apache.shiro.session.mgt.DefaultSessionManager 类:DefaultSessionManager是Shiro Session的默认管理器,实现了SessionManager接口。在默认情况下,SessionManager使用MemorySessionDAO作为Session的存储方式,也可以通过相应的配置,使用Redis或者JDBC等存储方式。

  4. org.apache.shiro.session.mgt.eis.SessionDAO 接口:SessionDAO是Shiro Session访问数据的接口,Shiro可以将Session保存到不同的存储方式中,如内存、Redis和JDBC等,需要通过SessionDAO来实现对不同存储方式的访问。

  5. org.apache.shiro.session.mgt.eis.CachingSessionDAO 类:CachingSessionDAO是Shiro Session访问数据的抽象类,主要用于为Session增加缓存。默认情况下,CachingSessionDAO和MemorySessionDAO配合使用。

  6. org.apache.shiro.session.mgt.eis.MemorySessionDAO 类:MemorySessionDAO是Shiro Session访问数据的实现,使用内存保存Session。

  7. org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO 类:EnterpriseCacheSessionDAO是Shiro Session访问数据的实现,基于Ehcache实现Session的持久化和缓存。

image.png

总结起来,Shiro的Session会话管理由Session接口、SessionManager、SessionDAO、CachingSessionDAO、MemorySessionDAO和EnterpriseCacheSessionDAO等组成,其中SessionManager是Shiro Session管理器的接口,用于管理和调用SessionDAO的实现类,SessionDAO是Session的数据访问接口,可以使用不同的Session存储方式,CachingSessionDAO是为Session增加缓存的抽象类。因此,在实际使用中,我们可以根据需要来选择和实现对应的Session管理方式,从而实现对Session的和管理和控制。