目录
- springboot:整合sa-token
- 一、简介
- 二、入门程序
- 1.添加依赖
- 2.sa-token配置类
- 3.测试controller
- 三、认证登录
- 1.mysql配置类
- 2.实体类
- 3.mapper
- 4.测试controller
- 四、密码加密
- 1.摘要加密
- 2.对称加密
- 3.非对称加密
- 4.Base64编码与解码
- 五、权限认证
- 1.获取当前账号权限码集合
- 2.权限认证
- 3.角色认证
- 4.权限通配符
- 5.测试controller
- 六、注解式鉴权
- 1.注册拦截器
- 2.使用注解鉴权
- 3.设定校验模式
- 4.角色权限双重校验
- 七、整合redis
- 1.添加依赖
- 2.redis配置类
springboot:整合sa-token
一、简介
Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证
、权限认证
、Session会话
、单点登录
、OAuth2.0
、微服务网关鉴权
等一系列权限相关问题
二、入门程序
1.添加依赖
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> | |
<dependency> | |
<groupId>cn.dev33</groupId> | |
<artifactId>sa-token-spring-boot-starter</artifactId> | |
<version>1.29.1.trial</version> | |
</dependency> | |
<dependency> | |
<groupId>cn.hutool</groupId> | |
<artifactId>hutool-all</artifactId> | |
<version>5.6.3</version> | |
</dependency> | |
<dependency> | |
<groupId>mysql</groupId> | |
<artifactId>mysql-connector-java</artifactId> | |
<version>5.1.47</version> | |
</dependency> | |
<dependency> | |
<groupId>com.alibaba</groupId> | |
<artifactId>druid</artifactId> | |
<version>1.0.29</version> | |
</dependency> | |
<dependency> | |
<groupId>org.mybatis.spring.boot</groupId> | |
<artifactId>mybatis-spring-boot-starter</artifactId> | |
<version>1.3.0</version> | |
</dependency> | |
<dependency> | |
<groupId>com.github.pagehelper</groupId> | |
<artifactId>pagehelper</artifactId> | |
<version>4.1.0</version> | |
</dependency> | |
<dependency> | |
<groupId>org.projectlombok</groupId> | |
<artifactId>lombok</artifactId> | |
<version>1.18.16</version> | |
</dependency> |
2.sa-token配置类
public class SaTokenConfiguration { | |
private static final String TOKEN_NAME = "sa-token"; | |
private static final Integer TIMEOUT = 2592000; | |
private static final Integer ACTIVITY_TIMEOUT = -1; | |
private static final String TOKEN_STYLE = "uuid"; | |
public SaTokenConfig saTokenConfig(){ | |
SaTokenConfig saTokenConfig = new SaTokenConfig(); | |
// token名称 (同时也是cookie名称) | |
saTokenConfig.setTokenName(TOKEN_NAME); | |
// token有效期,单位s 默认30天, -1代表永不过期 | |
saTokenConfig.setTimeout(TIMEOUT); | |
// token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 | |
saTokenConfig.setActivityTimeout(ACTIVITY_TIMEOUT); | |
// 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) | |
saTokenConfig.setAllowConcurrentLogin(true); | |
// 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) | |
saTokenConfig.setIsShare(true); | |
// token风格 | |
saTokenConfig.setTokenStyle(TOKEN_STYLE); | |
return saTokenConfig; | |
} | |
} |
3.测试controller
"/user/") | (|
public class UserController { | |
// 测试登录,浏览器访问: http://localhost:8081/user/doLogin?username=zhang&password=123456 | |
"doLogin") | (|
public String doLogin(String username, String password) { | |
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 | |
if("zhang".equals(username) && "123456".equals(password)) { | |
StpUtil.login(10001); | |
return "登录成功"; | |
} | |
return "登录失败"; | |
} | |
// 查询登录状态,浏览器访问: http://localhost:8081/user/isLogin | |
"isLogin") | (|
public String isLogin() { | |
return "当前会话是否登录:" + StpUtil.isLogin(); | |
} | |
} |
三、认证登录
1.mysql配置类
public class MysqlConfiguration { | |
public DataSource domeDataSource() throws Exception { | |
String mysqlHost = mysqlHost = "127.0.0.1"; | |
String mysqlPort = mysqlPort = "3306"; | |
String mysqlUsername = mysqlUsername = "root"; | |
String mysqlPassword = mysqlPassword = "root"; | |
String mysqlDB = mysqlDB = "test"; | |
DruidDataSource dataSource = new DruidDataSource(); | |
dataSource.setUrl("jdbc:mysql://" + mysqlHost + ":" + mysqlPort + "/" + mysqlDB | |
+ "?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true"); | |
dataSource.setPassword(mysqlPassword); | |
dataSource.setUsername(mysqlUsername); | |
dataSource.setMaxActive(100); | |
dataSource.setMaxWait(60000); | |
dataSource.setDriverClassName("com.mysql.jdbc.Driver"); | |
dataSource.setMinEvictableIdleTimeMillis(300000); | |
dataSource.setTimeBetweenEvictionRunsMillis(60000); | |
dataSource.setInitialSize(5); | |
dataSource.setMinIdle(1); | |
return dataSource; | |
} | |
public DataSourceTransactionManager domeTransactionManager() throws Exception { | |
return new DataSourceTransactionManager(domeDataSource()); | |
} | |
public SqlSessionFactoryBean sqlSessionFactory( DataSource dataSource, PageHelper pageHelper)throws Exception { | |
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); | |
sessionFactory.setDataSource(dataSource); | |
sessionFactory.setPlugins(new Interceptor[]{pageHelper}); | |
return sessionFactory; | |
} | |
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { | |
return new SqlSessionTemplate(sqlSessionFactory); | |
} | |
public PageHelper pageHelper() { | |
PageHelper pageHelper = new PageHelper(); | |
Properties p = new Properties(); | |
p.setProperty("offsetAsPageNum", "true"); | |
p.setProperty("rowBoundsWithCount", "true"); | |
p.setProperty("reasonable", "true"); | |
p.setProperty("dialect", "mysql"); | |
pageHelper.setProperties(p); | |
return pageHelper; | |
} | |
} |
2.实体类
public class User { | |
private int id; | |
private String username; | |
private String realName; | |
private String salt; | |
private String password; | |
private Long createTime; | |
private Long updateTime; | |
private Long deleteTime; | |
private int removed; | |
} |
3.mapper
@Repository | |
@Mapper | |
public interface UserMapper { | |
@Insert("INSERT INTO user (username,realName,password,salt,createTime,removed) VALUES (" + | |
"#{username},#{realName},#{password},#{salt},#{createTime},#{removed})") | |
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") | |
int createUser(User user); | |
@Select("select * from user where username=#{username} and removed=0 ") | |
User selectByUsername(@Param("username") String name); | |
} |
4.测试controller
"/user") | (|
public class UserController { | |
private UserMapper userMapper; | |
//创建用户 ---- http://localhost:8081/user/create | |
"/create") | (|
public SaResult createUser(){ User user | |
String md5BySalt = SaSecureUtil.md5BySalt(user.getPassword(), "qwertyuiop"); | |
user.setSalt("qwertyuiop"); | |
user.setPassword(md5BySalt); | |
user.setCreateTime(System.currentTimeMillis()); | |
userMapper.createUser(user); | |
return SaResult.ok(); | |
} | |
//登录 ---- http://localhost:8081/user/login | |
"/login") | (|
public SaResult doLogin("username") String name, ("password") String pwd) { ( | |
User user = userMapper.selectByUsername(name); | |
String password = SaSecureUtil.md5BySalt(pwd, user.getSalt()); | |
if (password.equals(user.getPassword())){ | |
StpUtil.login(10001); | |
return SaResult.ok("登录成功"); | |
} | |
return SaResult.error("登录失败"); | |
} | |
// 查询登录状态 ---- http://localhost:8081/user/isLogin | |
"isLogin") | (|
public SaResult isLogin() { | |
return SaResult.ok("是否登录:" + StpUtil.isLogin()); | |
} | |
// 查询 Token 信息 ---- http://localhost:8081/user/tokenInfo | |
"tokenInfo") | (|
public SaResult tokenInfo() { | |
return SaResult.data(StpUtil.getTokenInfo()); | |
} | |
// 测试注销 ---- http://localhost:8081/user/logout | |
"logout") | (|
public SaResult logout() { | |
StpUtil.logout(); | |
return SaResult.ok(); | |
} | |
} |
四、密码加密
1.摘要加密
// md5加密 | |
SaSecureUtil.md5("123456"); | |
// sha1加密 | |
SaSecureUtil.sha1("123456"); | |
// sha256加密 | |
SaSecureUtil.sha256("123456"); | |
// md5加盐加密: md5(md5(str) + md5(salt)) | |
SaSecureUtil.md5BySalt("123456", "salt"); |
2.对称加密
// 定义秘钥和明文 | |
String key = "123456"; | |
String text = "Sa-Token 一个轻量级java权限认证框架"; | |
// 加密 | |
String ciphertext = SaSecureUtil.aesEncrypt(key, text); | |
System.out.println("AES加密后:" + ciphertext); | |
// 解密 | |
String text2 = SaSecureUtil.aesDecrypt(key, ciphertext); | |
System.out.println("AES解密后:" + text2); |
3.非对称加密
// 定义私钥和公钥 | |
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAO+wmt01pwm9lHMdq7A8gkEigk0XKMfjv+4IjAFhWCSiTeP7dtlnceFJbkWxvbc7Qo3fCOpwmfcskwUc3VSgyiJkNJDs9ivPbvlt8IU2bZ+PBDxYxSCJFrgouVOpAr8ar/b6gNuYTi1vt3FkGtSjACFb002/68RKUTye8/tdcVilAgMBAAECgYA1COmrSqTUJeuD8Su9ChZ0HROhxR8T45PjMmbwIz7ilDsR1+E7R4VOKPZKW4Kz2VvnklMhtJqMs4MwXWunvxAaUFzQTTg2Fu/WU8Y9ha14OaWZABfChMZlpkmpJW9arKmI22ZuxCEsFGxghTiJQ3tK8npj5IZq5vk+6mFHQ6aJAQJBAPghz91Dpuj+0bOUfOUmzi22obWCBncAD/0CqCLnJlpfOoa9bOcXSusGuSPuKy5KiGyblHMgKI6bq7gcM2DWrGUCQQD3SkOcmia2s/6i7DUEzMKaB0bkkX4Ela/xrfV+A3GzTPv9bIBamu0VIHznuiZbeNeyw7sVo4/GTItq/zn2QJdBAkEA8xHsVoyXTVeShaDIWJKTFyT5dJ1TR++/udKIcuiNIap34tZdgGPI+EM1yoTduBM7YWlnGwA9urW0mj7F9e9WIQJAFjxqSfmeg40512KP/ed/lCQVXtYqU7U2BfBTg8pBfhLtEcOg4wTNTroGITwe2NjL5HovJ2n2sqkNXEio6Ji0QQJAFLW1Kt80qypMqot+mHhS+0KfdOpaKeMWMSR4Ij5VfE63WzETEeWAMQESxzhavN1WOTb3/p6icgcVbgPQBaWhGg=="; | |
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvsJrdNacJvZRzHauwPIJBIoJNFyjH47/uCIwBYVgkok3j+3bZZ3HhSW5Fsb23O0KN3wjqcJn3LJMFHN1UoMoiZDSQ7PYrz275bfCFNm2fjwQ8WMUgiRa4KLlTqQK/Gq/2+oDbmE4tb7dxZBrUowAhW9NNv+vESlE8nvP7XXFYpQIDAQAB"; | |
// 文本 | |
String text = "Sa-Token 一个轻量级java权限认证框架"; | |
// 使用公钥加密 | |
String ciphertext = SaSecureUtil.rsaEncryptByPublic(publicKey, text); | |
System.out.println("公钥加密后:" + ciphertext); | |
// 使用私钥解密 | |
String text2 = SaSecureUtil.rsaDecryptByPrivate(privateKey, ciphertext); | |
System.out.println("私钥解密后:" + text2); |
// 生成一对公钥和私钥,其中Map对象 (private=私钥, public=公钥) System.out.println(SaSecureUtil.rsaGenerateKeyPair());
4.Base64编码与解码
// 文本 | |
String text = "Sa-Token 一个轻量级java权限认证框架"; | |
// 使用Base64编码 | |
String base64Text = SaBase64Util.encode(text); | |
System.out.println("Base64编码后:" + base64Text); | |
// 使用Base64解码 | |
String text2 = SaBase64Util.decode(base64Text); | |
System.out.println("Base64解码后:" + text2); |
五、权限认证
1.获取当前账号权限码集合
/** | |
* 自定义权限验证接口扩展 | |
*/ | |
// 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展 | |
public class StpInterfaceImpl implements StpInterface { | |
/** | |
* 返回一个账号所拥有的权限码集合 | |
*/ | |
public List<String> getPermissionList(Object loginId, String loginKey) { | |
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限 | |
List<String> list = new ArrayList<>(); | |
list.add("101"); | |
list.add("user-add"); | |
list.add("user-delete"); | |
list.add("user-update"); | |
list.add("user-get"); | |
list.add("article-get"); | |
return list; | |
} | |
/** | |
* 返回一个账号所拥有的角色标识集合 | |
*/ | |
public List<String> getRoleList(Object loginId, String loginKey) { | |
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色 | |
List<String> list = new ArrayList<>(); | |
list.add("admin"); | |
list.add("super-admin"); | |
return list; | |
} | |
} |
2.权限认证
// 判断:当前账号是否含有指定权限, 返回true或false | |
StpUtil.hasPermission("user-update"); | |
// 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException | |
StpUtil.checkPermission("user-update"); | |
// 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过] | |
StpUtil.checkPermissionAnd("user-update", "user-delete"); | |
// 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可] | |
StpUtil.checkPermissionOr("user-update", "user-delete"); |
3.角色认证
在Sa-Token中,角色和权限可以独立验证
// 判断:当前账号是否拥有指定角色, 返回true或false | |
StpUtil.hasRole("super-admin"); | |
// 校验:当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException | |
StpUtil.checkRole("super-admin"); | |
// 校验:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过] | |
StpUtil.checkRoleAnd("super-admin", "shop-admin"); | |
// 校验:当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可] | |
StpUtil.checkRoleOr("super-admin", "shop-admin"); |
4.权限通配符
Sa-Token允许你根据通配符指定泛权限,例如当一个账号拥有user*
的权限时,user-add
、user-delete
、user-update
都将匹配通过
当一个账号拥有 "*"
权限时,他可以验证通过任何权限码 (角色认证同理)
// 当拥有 user* 权限时 | |
StpUtil.hasPermission("user-add"); // true | |
StpUtil.hasPermission("user-update"); // true | |
StpUtil.hasPermission("art-add"); // false | |
// 当拥有 *-delete 权限时 | |
StpUtil.hasPermission("user-add"); // false | |
StpUtil.hasPermission("user-delete"); // true | |
StpUtil.hasPermission("art-delete"); // true | |
// 当拥有 *.js 权限时 | |
StpUtil.hasPermission("index.js"); // true | |
StpUtil.hasPermission("index.css"); // false | |
StpUtil.hasPermission("index.html"); // false |
5.测试controller
// 测试角色接口, 浏览器访问: http://localhost:8081/user/testRole | |
public SaResult testRole() { | |
System.out.println("======================= 进入方法,测试角色接口 ========================= "); | |
System.out.println("是否具有角色标识 user " + StpUtil.hasRole("user")); | |
System.out.println("是否具有角色标识 admin " + StpUtil.hasRole("admin")); | |
System.out.println("没有admin权限就抛出异常"); | |
StpUtil.checkRole("admin"); | |
System.out.println("在【admin、user】中只要拥有一个就不会抛出异常"); | |
StpUtil.checkRoleOr("admin", "user"); | |
System.out.println("在【admin、user】中必须全部拥有才不会抛出异常"); | |
StpUtil.checkRoleAnd("admin", "user"); | |
System.out.println("角色测试通过"); | |
return SaResult.ok(); | |
} | |
// 测试权限接口, 浏览器访问: http://localhost:8081/user/testJur | |
public SaResult testJur() { | |
System.out.println("======================= 进入方法,测试权限接口 ========================= "); | |
System.out.println("是否具有权限101" + StpUtil.hasPermission("101")); | |
System.out.println("是否具有权限user-add" + StpUtil.hasPermission("user-add")); | |
System.out.println("是否具有权限article-get" + StpUtil.hasPermission("article-get")); | |
System.out.println("没有user-add权限就抛出异常"); | |
StpUtil.checkPermission("user-add"); | |
System.out.println("在【101、102】中只要拥有一个就不会抛出异常"); | |
StpUtil.checkPermissionOr("101", "102"); | |
System.out.println("在【101、102】中必须全部拥有才不会抛出异常"); | |
StpUtil.checkPermissionAnd("101", "102"); | |
System.out.println("权限测试通过"); | |
return SaResult.ok(); | |
} |
六、注解式鉴权
@SaCheckLogin
: 登录认证 —— 只有登录之后才能进入该方法@SaCheckRole("admin")
: 角色认证 —— 必须具有指定角色标识才能进入该方法@SaCheckPermission("user:add")
: 权限认证 —— 必须具有指定权限才能进入该方法@SaCheckSafe
: 二级认证校验 —— 必须二级认证之后才能进入该方法@SaCheckBasic
: HttpBasic认证 —— 只有通过 Basic 认证后才能进入该方法
1.注册拦截器
public class SaTokenConfigure implements WebMvcConfigurer { | |
// 注册Sa-Token的注解拦截器,打开注解式鉴权功能 | |
public void addInterceptors(InterceptorRegistry registry) { | |
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关) | |
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**"); | |
} | |
} |
在高版本SpringBoot (≥2.6.x)
版本下,需要额外添加@EnableWebMvc
注解才可以使注册拦截器生效
2.使用注解鉴权
// 登录认证:只有登录之后才能进入该方法 http://localhost:8081/user/info | |
"/info") | (|
public String info() { | |
return "查询用户信息"; | |
} | |
// 角色认证:必须具有指定角色才能进入该方法 http://localhost:8081/user/add | |
"super-admin") | (|
"/add") | (|
public String add() { | |
return "用户增加"; | |
} |
3.设定校验模式
@SaCheckRole
与@SaCheckPermission
注解可设置校验模式
// 注解式鉴权:只要具有其中一个权限即可通过校验 | |
@RequestMapping("atJurOr") | |
@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR) | |
public SaResult atJurOr() { | |
return SaResult.ok("用户信息"); | |
} |
SaMode.AND
, 标注一组权限,会话必须全部具有才可通过校验SaMode.OR
, 标注一组权限,会话只要具有其一即可通过校验
4.角色权限双重校验
// 注解式鉴权:只要具有其中一个权限即可通过校验 | |
@RequestMapping("userAdd") | |
@SaCheckPermission(value = "user-add", orRole = "admin") | |
public SaResult userAdd() { | |
return SaResult.ok("用户信息"); | |
} |
orRole 字段代表权限认证未通过时的次要选择,两者只要其一认证成功即可通过校验,其有三种写法:
- 写法一:
orRole = "admin"
,代表需要拥有角色 admin 。 - 写法二:
orRole = {"admin", "manager", "staff"}
,代表具有三个角色其一即可。 - 写法三:
orRole = {"admin, manager, staff"}
,代表必须同时具有三个角色
七、整合redis
1.添加依赖
<!-- sa-token整合redis (使用jackson序列化方式) --> | |
<dependency> | |
<groupId>cn.dev33</groupId> | |
<artifactId>sa-token-dao-redis-jackson</artifactId> | |
<version>${sa-token-version}</version> | |
</dependency> | |
<!-- 提供redis连接池 --> | |
<dependency> | |
<groupId>org.apache.commons</groupId> | |
<artifactId>commons-pool2</artifactId> | |
</dependency> |
2.redis配置类
public class RedisConfiguration{ | |
//配置redis的过期时间 | |
private static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer(); | |
private static final GenericJackson2JsonRedisSerializer JSON_SERIALIZER = new GenericJackson2JsonRedisSerializer(); | |
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { | |
RedisTemplate<String, Object> template = new RedisTemplate<>(); | |
template.setConnectionFactory(lettuceConnectionFactory); | |
//key的序列方式 | |
template.setKeySerializer(STRING_SERIALIZER); | |
//hashKey的序列方式 | |
template.setHashKeySerializer(STRING_SERIALIZER); | |
//value的序列方式 | |
template.setValueSerializer(JSON_SERIALIZER); | |
//value hashmap序列化 | |
template.setHashValueSerializer(JSON_SERIALIZER); | |
return template; | |
} | |
public GenericObjectPoolConfig poolConfig(){ | |
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); | |
//控制一个pool可分配多少个jedis实例 | |
poolConfig.setMaxTotal(500); | |
//最大空闲数 | |
poolConfig.setMaxIdle(200); | |
//每次释放连接的最大数目,默认是3 | |
poolConfig.setNumTestsPerEvictionRun(1024); | |
//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 | |
poolConfig.setTimeBetweenEvictionRunsMillis(30000); | |
//连接的最小空闲时间 默认1800000毫秒(30分钟) | |
poolConfig.setMinEvictableIdleTimeMillis(-1); | |
poolConfig.setSoftMinEvictableIdleTimeMillis(10000); | |
//最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 | |
poolConfig.setMaxWaitMillis(1500); | |
poolConfig.setTestOnBorrow(true); | |
poolConfig.setTestWhileIdle(true); | |
poolConfig.setTestOnReturn(false); | |
poolConfig.setJmxEnabled(true); | |
poolConfig.setBlockWhenExhausted(false); | |
return poolConfig; | |
} | |
public LettuceConnectionFactory lettuceConnectionFactory() { | |
LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder() | |
.poolConfig(poolConfig()) | |
.build(); | |
// 单机redis | |
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(); | |
redisConfig.setHostName("127.0.0.1"); | |
redisConfig.setPort(6379); | |
redisConfig.setDatabase(0); | |
// 哨兵redis | |
//RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration(); | |
// 集群redis | |
// RedisClusterConfiguration redisConfig = new RedisClusterConfiguration(); | |
// Set<RedisNode> nodeses = new HashSet<>(); | |
// String[] hostses = nodes.split("-"); | |
// for (String h : hostses) { | |
// h = h.replaceAll("\\s", "").replaceAll("\n", ""); | |
// if (!"".equals(h)) { | |
// String host = h.split(":")[0]; | |
// int port = Integer.valueOf(h.split(":")[1]); | |
// nodeses.add(new RedisNode(host, port)); | |
// } | |
// } | |
// redisConfig.setClusterNodes(nodeses); | |
// // 跨集群执行命令时要遵循的最大重定向数量 | |
// redisConfig.setMaxRedirects(3); | |
// redisConfig.setPassword(password); | |
return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration); | |
} | |
} |
Sa-Token-Redis 集成包的版本尽量与 Sa-Token-Starter 集成包的版本一致,否则可能出现兼容性问题
调用登录接口后,查看redis可视化界面