Springboot学习SpringBoot集成Shiro前后端分离使用redis做缓存个人博客搭建

Posted 毛_三月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot学习SpringBoot集成Shiro前后端分离使用redis做缓存个人博客搭建相关的知识,希望对你有一定的参考价值。

shiro-redis

alexxiyang / shiro-redis

shiro 只提供 ehcache 和 concurrentHashMap 的支持。这里有一个 shiro 可以使用的 redis 缓存实现。希望它会帮助你!

下载

您可以使用以下 2 种方式之一包含shiro-redis到您的项目中

  • 用于git clone https://github.com/alexxiyang/shiro-redis.git将项目克隆到本地工作区并自行构建 jar 文件
  • 添加maven依赖
<dependency>
    <groupId>org.crazycake</groupId>
    <artifactId>shiro-redis</artifactId>
    <version>3.3.1</version>
</dependency>

注意:
3.3.0 错误地在java11 中编译。请使用java8编译的3.3.1

shiro-core/jedis 版本对比图

shiro-redisshirojedis
3.2.31.3.22.9.0
3.3.0 (java11)1.6.03.3.0
3.3.1 (java8)1.6.03.3.0

使用前

这是您需要了解的第一件事。Shiro-redis 需要一个 id 字段来标识您在 Redis 中的授权对象。所以请确保你的主类有一个字段,你可以得到这个对象的唯一 id。请通过以下方式设置此 ID 字段名称cacheManager.principalIdFieldName = <your id field name of principal object>

例如:

如果你这样创建SimpleAuthenticationInfo

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername(usernamePasswordToken.getUsername());
    return new SimpleAuthenticationInfo(userInfo, "123456", getName());
}

那么userInfo对象就是你的主要对象。您需要确保UserInfoRedis 有一个唯一的字段来识别它。以userId为例:

public class UserInfo implements Serializable{

    private Integer userId

    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserId() {
        return this.userId;
    }
}

将 userId 作为 的值cacheManager.principalIdFieldName,如下所示:

cacheManager.principalIdFieldName = userId

如果你使用的是 Spring,配置应该是

<property name="principalIdFieldName" value="userId" />

然后shiro-redis将调用userInfo.getUserId()获取 id 以保存 Redis 对象。

如何配置?

您可以配置shiro-redisinshiro.ini或 inspring-*.xml

设置文件

下面是 shiro.ini 的配置示例。

Redis 独立

如果您在独立模式下运行 Redis

[main]
#====================================
# shiro-redis configuration [start]
#====================================

#===================================
# Redis Manager [start]
#===================================

# Create redisManager
redisManager = org.crazycake.shiro.RedisManager

# Redis host. If you don't specify host the default value is 127.0.0.1:6379
redisManager.host = 127.0.0.1:6379

#===================================
# Redis Manager [end]
#===================================

#=========================================
# Redis session DAO [start]
#=========================================

# Create redisSessionDAO
redisSessionDAO = org.crazycake.shiro.RedisSessionDAO

# Use redisManager as cache manager
redisSessionDAO.redisManager = $redisManager

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager

sessionManager.sessionDAO = $redisSessionDAO

securityManager.sessionManager = $sessionManager

#=========================================
# Redis session DAO [end]
#=========================================

#==========================================
# Redis cache manager [start]
#==========================================

# Create cacheManager
cacheManager = org.crazycake.shiro.RedisCacheManager

# Principal id field name. The field which you can get unique id to identify this principal.
# For example, if you use UserInfo as Principal class, the id field maybe `id`, `userId`, `email`, etc.
# Remember to add getter to this id field. For example, `getId()`, `getUserId()`, `getEmail()`, etc.
# Default value is id, that means your principal object must has a method called `getId()`
cacheManager.principalIdFieldName = id

# Use redisManager as cache manager
cacheManager.redisManager = $redisManager

securityManager.cacheManager = $cacheManager

#==========================================
# Redis cache manager [end]
#==========================================

#=================================
# shiro-redis configuration [end]
#=================================

有关完整的可配置选项列表,请检查Configurable Options

这是一个教程项目,让您了解如何shiro-redisshiro.ini.

Redis哨兵

如果您使用的是Redis Sentinel,请将redisManager独立版本的配置替换为以下内容:

#===================================
# Redis Manager [start]
#===================================

# Create redisManager
redisManager = org.crazycake.shiro.RedisSentinelManager

# Sentinel host. If you don't specify host the default value is 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
redisManager.host = 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381

# Sentinel master name
redisManager.masterName = mymaster

#===================================
# Redis Manager [end]
#===================================

有关完整的可配置选项列表,请检查Configurable Options

Redis 集群

如果您使用的是redis集群,请将redisManager独立版本的配置替换为以下内容:

#===================================
# Redis Manager [start]
#===================================

# Create redisManager
redisManager = org.crazycake.shiro.RedisClusterManager

# Redis host and port list
redisManager.host = 192.168.21.3:7000,192.168.21.3:7001,192.168.21.3:7002,192.168.21.3:7003,192.168.21.3:7004,192.168.21.3:7005

#===================================
# Redis Manager [end]
#===================================

有关完整的可配置选项列表,请检查Configurable Options

Spring

如果您使用的是 Spring

Redis 独立

如果您在独立模式下运行 Redis

<!-- shiro-redis configuration [start] -->

<!-- Redis Manager [start] -->
<bean id="redisManager" class="org.crazycake.shiro.RedisManager">
    <property name="host" value="127.0.0.1:6379"/>
</bean>
<!-- Redis Manager [end] -->

<!-- Redis session DAO [start] -->
<bean id="redisSessionDAO" class="org.crazycake.shiro.RedisSessionDAO">
    <property name="redisManager" ref="redisManager" />
</bean>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="sessionDAO" ref="redisSessionDAO" />
</bean>
<!-- Redis session DAO [end] -->

<!-- Redis cache manager [start] -->
<bean id="cacheManager" class="org.crazycake.shiro.RedisCacheManager">
    <property name="redisManager" ref="redisManager" />
</bean>
<!-- Redis cache manager [end] -->

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="sessionManager" ref="sessionManager" />
    <property name="cacheManager" ref="cacheManager" />

    <!-- other configurations -->
    <property name="realm" ref="exampleRealm"/>
    <property name="rememberMeManager.cipherKey" value="kPH+bIxk5D2deZiIxcaaaA==" />
</bean>

<!-- shiro-redis configuration [end] -->

有关完整的可配置选项列表,请检查Configurable Options

这里有一个教程项目,让你了解如何shiro-redis在spring配置文件中进行配置。

Redis哨兵

如果使用redis sentinel,请将redisManager单机版的配置改为如下:

<!-- shiro-redis configuration [start] -->
<!-- shiro redisManager -->
<bean id="redisManager" class="org.crazycake.shiro.RedisSentinelManager">
    <property name="host" value="127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381"/>
    <property name="masterName" value="mymaster"/>
</bean>

有关完整的可配置选项列表,请检查Configurable Options

Redis 集群

如果使用redis集群,请将redisManagerstandalone版本的配置改为如下:

<!-- shiro-redis configuration [start] -->
<!-- shiro redisManager -->
<bean id="redisManager" class="org.crazycake.shiro.RedisClusterManager">
    <property name="host" value="192.168.21.3:7000,192.168.21.3:7001,192.168.21.3:7002,192.168.21.3:7003,192.168.21.3:7004,192.168.21.3:7005"/>
</bean>

有关完整的可配置选项列表,请检查Configurable Options

序列化器 Serializer

由于 redis 只接受byte[],就会出现序列化问题。Shiro-redisStringSerializer用作键序列化器和ObjectSerializer值序列化器。你可以使用你自己的自定义序列化器,只要这个自定义序列化器实现org.crazycake.shiro.serializer.RedisSerializer

例如,我们可以像这样更改 keySerializer 的字符集

# If you want change charset of keySerializer or use your own custom serializer, you need to define serializer first
#
# cacheManagerKeySerializer = org.crazycake.shiro.serializer.StringSerializer

# Supported encodings refer to https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html
# UTF-8, UTF-16, UTF-32, ISO-8859-1, GBK, Big5, etc
#
# cacheManagerKeySerializer.charset = UTF-8

# cacheManager.keySerializer = $cacheManagerKeySerializer

您可以使用自定义序列化程序替换这 4 个选项:

  • cacheManager.keySerializer
  • cacheManager.valueSerializer
  • redisSessionDAO.keySerializer
  • redisSessionDAO.valueSerializer

可配置选项 Configurable Options

以下是您可以在shiro-redis配置文件中使用的所有可用选项。

Redis管理器

TitleDefaultDescription
host127.0.0.1:6379Redis 主机。如果您不指定主机,则默认值为127.0.0.1:6379. 如果你在哨兵模式或集群模式下运行 redis,用逗号分隔主机名,如127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
masterNamemymaster仅用于哨兵模式 Redis哨兵模式的主节点
timeout2000Redis 连接超时。jedis 尝试连接到 redis 服务器超时(以毫秒为单位)
soTimeout2000仅用于哨兵模式或集群模式 jedis尝试从redis服务器读取数据的超时时间
maxAttempts3仅用于集群模式 最大尝试连接到服务器
passwordRedis密码
database0Redis 数据库。默认值为 0
jedisPoolConfignew redis.clients.jedis.JedisPoolConfig()JedisPoolConfig. 您可以创建自己的 JedisPoolConfig 实例并根据需要设置属性 大多数情况下,您不需要设置 jedisPoolConfig 这里是一个示例。 jedisPoolConfig = redis.clients.jedis.JedisPoolConfig jedisPoolConfig.testWhileIdle = false redisManager.jedisPoolConfig = jedisPoolConfig
count100扫描计数。Shiro-redis 使用 Scan 来获取键,因此您可以定义每次迭代返回的元素数量。
jedisPoolnull仅用于哨兵模式或单模式 您可以创建自己的 JedisPool 实例并根据需要设置属性

RedisSessionDAO

TitleDefaultDescription
redisManager您刚刚在上面配置的RedisManager(必需)
expire-2Redis 缓存键/值过期时间。过期时间以秒为单位。 特殊值: -1: no expire -2:与会话超时相同 默认值:-2 注意:确保过期时间长于会话超时。
keyPrefixshiro:session:为会话管理自定义您的 redis 密钥前缀 注意:请记住在前缀末尾添加冒号。
sessionInMemoryTimeout1000当我们登录时,doReadSession(sessionId)会被 shiro 调用大约 10 次。所以shiro-redis将Session保存在ThreadLocal中来缓解这个问题。sessionInMemoryTimeout 是 ThreadLocal 中 Session 的到期时间。 大多数情况下,您不需要更改它。
sessionInMemoryEnabledtrue是否在 ThreadLocal 中启用临时保存会话
keySerializerorg.crazycake.shiro.serializer.StringSerializer缓存管理器的key serializer 你可以改变key serializer 的实现或者StringSerializer 的编码。 支持的编码是指支持的编码。如UTF-8, UTF-16, UTF-32, ISO-8859-1, GBK, Big5, 等 更多细节请查看Serializer
valueSerializerorg.crazycake.shiro.serializer.ObjectSerializer缓存管理器的值序列化器 您可以更改值序列化器的实现 有关更多详细信息,请查看Serializer

CacheManager 缓存管理器

TitleDefaultDescription
redisManager您刚刚在上面配置的RedisManager(必需)
principalIdFieldNameid主体 ID 字段名称。您可以获得唯一 ID 来标识此主体的字段。 例如,如果您使用 UserInfo 作为 Principal 类,则 id 字段可能iduserIdemail、 等。 请记住将 getter 添加到此 id 字段。例如,getId(), getUserId(),getEmail()等。 默认值是id,这意味着您的主体对象必须有一个方法调用getId()
expire1800Redis 缓存键/值过期时间。 过期时间以秒为单位。
keyPrefixshiro:cache:自定义您的 redis 键前缀以进行缓存管理 注意:请记住在前缀末尾添加冒号。
keySerializerorg.crazycake.shiro.serializer.StringSerializer缓存管理器的key serializer 你可以改变key serializer 的实现或者StringSerializer 的编码。 支持的编码是指支持的编码。如UTF-8, UTF-16, UTF-32, ISO-8859-1, GBK, Big5, 等 更多细节请查看Serializer
valueSerializerorg.crazycake.shiro.serializer.ObjectSerializer缓存管理器的值序列化器 您可以更改值序列化器的实现 有关更多详细信息,请查看Serializer

弹簧启动器 Spring boot starter

使用Spring-Boot集成是集成shiro-redis到基于 Spring 的应用程序的最简单方法。

注意:shiro-redis-spring-boot-starter版本3.2.1基于shiro-spring-boot-web-starter版本1.4.0-RC2

首先shiro-redis在您的应用程序类路径中包含Spring boot starter 依赖项

<dependency>
    <groupId>org.crazycake</groupId>
    <artifactId>shiro-redis-spring-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>

下一步取决于您是创建了自己的SessionManager还是SessionsSecurityManager.

如果您还没有创建自己的SessionManagerSessionsSecurityManager

如果您没有自己的SessionManagerSessionsSecurityManager在您的配置中,shiro-redis-spring-boot-starter将创建RedisSessionDAORedisCacheManager为您。然后将它们注入SessionManagerSessionsSecurityManager自动注入。所以,你都准备好了。享受吧!

如果您已经创建了自己的SessionManagerSessionsSecurityManager

如果您创建了自己的SessionManagerSessionsSecurityManager喜欢这样的:

@Bean
public SessionsSecurityManager securityManager(List<Realm> realms) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realms);
    
    // other stuff...
    
    return securityManager;
}

然后注入redisSessionDAO和已经redisCacheManager创建的shiro-redis-spring-boot-starter

@Autowired
RedisSessionDAO redisSessionDAO;

@Autowired
RedisCacheManager redisCacheManager;

将它们注入您自己的SessionManagerSessionsSecurityManager

@Bean
public SessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();

    // inject redisSessionDAO
    sessionManager.setSessionDAO(redisSessionDAO);
    
    // other stuff...
    
    return sessionManager;
}

@Bean
public SessionsSecurityManager securityManager(List<Realm> realms, SessionManager sessionManager) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realms);

    //inject sessionManager
    securityManager.setSessionManager(sessionManager);

    // inject redisCacheManager
    securityManager.setCacheManager(redisCacheManager);
    
    // other stuff...
    
    return securityManager;
}

有关完整示例,请参阅shiro-redis-spring-boot-tutorial

配置属性 Configuration Properties

以下是您可以在 Spring-boot 启动器配置中使用的所有可用选项

标题 Title默认 Default说明 Description
shiro-redis.enabledtrue启用 shiro-redis 的 Spring 模块
shiro-redis.redis-manager.deploy-modestandaloneRedis 部署模式。选项: standalone, sentinel, ‘集群’
shiro-redis.redis-manager.host127.0.0.1:6379Redis 主机。如果您不指定主机,则默认值为127.0.0.1:6379. 如果你在哨兵模式或集群模式下运行 redis,用逗号分隔主机名,如127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
shiro-redis.redis-manager.master-namemymaster仅用于哨兵模式 Redis哨兵模式的主节点
shiro-redis.redis-manager.timeout2000Redis 连接超时。jedis 尝试连接到 redis 服务器超时(以毫秒为单位)
shiro-redis.redis-manager.so-timeout2000仅用于哨兵模式或集群模式 jedis尝试从redis服务器读取数据的超时时间
shiro-redis.redis-manager.max-attempts3仅用于集群模式 最大尝试连接到服务器
shiro-redis.redis-manager.passwordRedis密码
shiro-redis.redis-manager.database0Redis 数据库。默认值为 0
shiro-redis.redis-manager.count100扫描计数。Shiro-redis 使用 Scan 来获取键,因此您可以定义每次迭代返回的元素数量。
shiro-redis.session-dao.expire-2Redis 缓存键/值过期时间。过期时间以秒为单位。 特殊值: -1: no expire -2:与会话超时相同 默认值:-2 注意:确保过期时间长于会话超时。
shiro-redis.session-dao.key-prefixshiro:session:为会话管理自定义您的 redis 密钥前缀 注意:请记住在前缀末尾添加冒号。
shiro-redis.session-dao.session-in-memory-timeout1000当我们登录时,doReadSession(sessionId)会被 shiro 调用大约 10 次。所以shiro-redis将Session保存在ThreadLocal中来缓解这个问题。sessionInMemoryTimeout 是 ThreadLocal 中 Session 的到期时间。 大多数情况下,您不需要更改它。
shiro-redis.session-dao.session-in-memory-enabledtrue是否在 ThreadLocal 中启用临时保存会话
shiro-redis.cache-manager.principal-id-field-nameid主体 ID 字段名称。您可以获得唯一 ID 来标识此主体的字段。 例如,如果您使用 UserInfo 作为 Principal 类,则 id 字段可能iduserIdemail、 等。 请记住将 getter 添加到此 id 字段。例如,getId(), getUserId(),getEmail()等。 默认值是id,这意味着您的主体对象必须有一个方法调用getId()
shiro-redis.cache-manager.expire1800Redis 缓存键/值过期时间。 过期时间以秒为单位。
shiro-redis.cache-manager.key-prefixshiro:cache:自定义您的 redis 键前缀以进行缓存管理 注意:请记住在前缀末尾添加冒号。

Working with spring-boot-devtools

如果您使用shiro-redisspring-boot-devtools. 请将此行添加到resources/META-INF/spring-devtools.properties(如果没有此文件,则创建它):

restart.include.shiro-redis=/shiro-[\\\\w-\\\\.]+jar

如果您发现任何错误

欢迎留言

如果您在学习这篇文章之前对Shiro不了解或者掌握程度较低,建议先阅读博主我这篇文章

【Springboot学习】Shiro快速入门及与SpringBoot集成

如果您觉得学有余力,欢迎继续阅读如下文章

【Java全栈】Java全栈学习路线及项目全资料总结【JavaSE+Web基础+大前端进阶+SSM+微服务+Linux+JavaEE】

可爱的人给一个三连吧

以上是关于Springboot学习SpringBoot集成Shiro前后端分离使用redis做缓存个人博客搭建的主要内容,如果未能解决你的问题,请参考以下文章

Springboot学习Shiro快速入门及与SpringBoot集成

SpringBoot 学习笔记 -- [spring Boot配置文件之YAML格式, springBoot自动配置浅入,springboot集成JDBC]

大数据-kafka学习——集成SpringBoot

kafka学习:kafka简单命令操作&springboot+kafka

开源框架JeeSite集成SpringBoot实例

第131天学习打卡(ElastiSearch 集成SpringBoot)