介绍
Shiro中的Session管理是Shiro框架的一个核心组件,用于管理用户会话信息。Shiro的Session管理包括会话创建、销毁、过期等功能以及session存储策略,Shiro已经提供了完整的企业级Session管理。
Shiro的Session管理提供了以下的主要功能:
-
会话创建:当用户登录时,Shiro会创建一个会话并保存到会话存储中。用户在访问有权限控制的资源时,Shiro会检查会话是否存在,如果不存在则会创建一个新的会话。
-
会话过期:Shiro会自动检查会话是否过期。当会话过期时,Shiro会自动将会话标记为无效并从存储中移除。
-
退出登录和会话终止:当用户退出登录或关闭浏览器时,Shiro会自动将会话标记为无效并从存储中移除。
-
Session的存储策略:Shiro提供了多种Session的存储策略,默认情况下,Shiro使用内存存储,但在实际生产环境中,往往使用更为安全的分布式缓存存储(如Redis、Memcached).
在Shiro中,可以通过以下的几种方式进行Session管理:
-
内存存储:所有的Session信息都会保存在内存中。这种方式在开发调试时使用比较方便,但在高并发、分布式环境下不够稳定。
-
Cookie 存储:将Session信息保存在Cookie中。当用户请求资源时,Shiro会解析Cookie中的Session信息并进行验证。这种方式简便,但不够安全和可靠。
-
URL 重写:将Session ID 保存在URL中,通过 URL 分发给浏览器端。在访问资源时,浏览器会自动发送URL中包含的Session ID,Shiro会解析并进行验证。但是这种方式存在泄漏 Session ID 的风险。
-
缓存存储:将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
-
getSession:获取当前请求的Session对象,如果当前请求中没有Session,则创建一个新的Session。 -
setAttribute:设置Session属性,通过Key-Value的形式来实现存储。 -
getAttribute:获取Session属性,通过Key获取对应的Value。 -
removeAttribute:移除Session中存储的某个属性。 -
getId:获取Session ID,在会话过程中,Session ID是唯一的标识。 -
getCreationTime:获取Session创建时间。 -
getLastAccessTime:获取Session最后访问时间。 -
getTimeout:获取Session过期时间。如果Session在这个时间内没有操作,则认为Session过期。 -
setTimeout:设置Session的过期时间。 -
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会话管理的实现和继承体系:
-
org.apache.shiro.session.Session接口:Session接口是Shiro Session的基本接口,定义了Session的基本属性和操作方法,包括获取Session ID、获取、设置Session属性、获取过期时间、判断是否过期、设置过期时间、退出登录等方法。 -
org.apache.shiro.session.mgt.SessionManager接口:SessionManager是Shiro Session管理器的接口,可以创建Session、获取Session、销毁Session、验证Session等管理操作。 -
org.apache.shiro.session.mgt.DefaultSessionManager类:DefaultSessionManager是Shiro Session的默认管理器,实现了SessionManager接口。在默认情况下,SessionManager使用MemorySessionDAO作为Session的存储方式,也可以通过相应的配置,使用Redis或者JDBC等存储方式。 -
org.apache.shiro.session.mgt.eis.SessionDAO接口:SessionDAO是Shiro Session访问数据的接口,Shiro可以将Session保存到不同的存储方式中,如内存、Redis和JDBC等,需要通过SessionDAO来实现对不同存储方式的访问。 -
org.apache.shiro.session.mgt.eis.CachingSessionDAO类:CachingSessionDAO是Shiro Session访问数据的抽象类,主要用于为Session增加缓存。默认情况下,CachingSessionDAO和MemorySessionDAO配合使用。 -
org.apache.shiro.session.mgt.eis.MemorySessionDAO类:MemorySessionDAO是Shiro Session访问数据的实现,使用内存保存Session。 -
org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO类:EnterpriseCacheSessionDAO是Shiro Session访问数据的实现,基于Ehcache实现Session的持久化和缓存。
总结起来,Shiro的Session会话管理由Session接口、SessionManager、SessionDAO、CachingSessionDAO、MemorySessionDAO和EnterpriseCacheSessionDAO等组成,其中SessionManager是Shiro Session管理器的接口,用于管理和调用SessionDAO的实现类,SessionDAO是Session的数据访问接口,可以使用不同的Session存储方式,CachingSessionDAO是为Session增加缓存的抽象类。因此,在实际使用中,我们可以根据需要来选择和实现对应的Session管理方式,从而实现对Session的和管理和控制。