SaToken接口鉴权
This commit is contained in:
@@ -68,6 +68,18 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson 组件 -->
|
||||
<dependency>
|
||||
<groupId>top.crushtj</groupId>
|
||||
<artifactId>xiaoyi-spring-boot-starter-jackson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -32,7 +32,6 @@ public class SaTokenConfigure {
|
||||
.check(r -> StpUtil.checkLogin()) // 校验是否登录
|
||||
;
|
||||
|
||||
SaRouter.match("/auth/user/logout", r -> StpUtil.checkPermission("user"));
|
||||
// 权限认证 -- 不同模块, 校验不同权限
|
||||
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
||||
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
package top.crushtj.xiaoyi.gateway.auth;
|
||||
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.crushtj.xiaoyi.gateway.constant.RedisKeyConstants;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
@@ -17,15 +28,80 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class StpInterfaceImpl implements StpInterface {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
log.info("## 获取用户权限列表, loginId: {}", loginId);
|
||||
return List.of();
|
||||
// 构建 用户-角色 Redis Key
|
||||
String userRolesKey = RedisKeyConstants.buildUserRoleKey(Long.valueOf(loginId.toString()));
|
||||
|
||||
// 根据用户 ID ,从 Redis 中获取该用户的角色集合
|
||||
String useRolesValue = redisTemplate.opsForValue()
|
||||
.get(userRolesKey);
|
||||
|
||||
if (StringUtils.isBlank(useRolesValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 将 JSON 字符串转换为 List<String> 角色集合
|
||||
List<String> userRoleKeys = objectMapper.readValue(useRolesValue, new TypeReference<>() {
|
||||
});
|
||||
|
||||
if (CollUtil.isNotEmpty(userRoleKeys)) {
|
||||
// 查询这些角色对应的权限
|
||||
// 构建 角色-权限 Redis Key 集合
|
||||
List<String> rolePermissionsKeys = userRoleKeys.stream()
|
||||
.map(RedisKeyConstants::buildRolePermissionsKey)
|
||||
.toList();
|
||||
|
||||
// 通过 key 集合批量查询权限,提升查询性能。
|
||||
List<String> rolePermissionsValues = Objects.requireNonNull(redisTemplate.opsForValue()
|
||||
.multiGet(rolePermissionsKeys))
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
|
||||
if (CollUtil.isNotEmpty(rolePermissionsValues)) {
|
||||
List<String> permissions = Lists.newArrayList();
|
||||
|
||||
// 遍历所有角色的权限集合,统一添加到 permissions 集合中
|
||||
rolePermissionsValues.forEach(jsonValue -> {
|
||||
try {
|
||||
// 将 JSON 字符串转换为 List<String> 权限集合
|
||||
List<String> rolePermissions = objectMapper.readValue(jsonValue, new TypeReference<>() {
|
||||
});
|
||||
permissions.addAll(rolePermissions);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("==> JSON 解析错误: ", e);
|
||||
}
|
||||
});
|
||||
|
||||
// 返回此用户所拥有的权限
|
||||
return permissions;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
log.info("## 获取用户角色列表, loginId: {}", loginId);
|
||||
return List.of();
|
||||
String userRolesKey = RedisKeyConstants.buildUserRoleKey(Long.valueOf(loginId.toString()));
|
||||
String useRolesValue = redisTemplate.opsForValue()
|
||||
.get(userRolesKey);
|
||||
if (StringUtils.isBlank(useRolesValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 将 JSON 字符串转换为 List<String> 集合
|
||||
return objectMapper.readValue(useRolesValue, new TypeReference<>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package top.crushtj.xiaoyi.gateway.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RedisTemplateConfig
|
||||
* @description Redis 配置类
|
||||
* @date 2026/01/12 19:13
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class RedisTemplateConfig {
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(@NonNull RedisConnectionFactory connectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
// 设置 RedisTemplate 的连接工厂
|
||||
redisTemplate.setConnectionFactory(connectionFactory);
|
||||
|
||||
// 使用 StringRedisSerializer 来序列化和反序列化 redis 的 key 值,确保 key 是可读的字符串
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
|
||||
// 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值, 确保存储的是 JSON 格式
|
||||
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
redisTemplate.setValueSerializer(serializer);
|
||||
redisTemplate.setHashValueSerializer(serializer);
|
||||
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package top.crushtj.xiaoyi.gateway.constant;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RedisKeyConstants
|
||||
* @date 2026/2/3 15:24
|
||||
* @description Redis key 常量
|
||||
*/
|
||||
|
||||
public class RedisKeyConstants {
|
||||
|
||||
/**
|
||||
* 用户对应角色集合 KEY 前缀
|
||||
*/
|
||||
private static final String USER_ROLES_KEY_PREFIX = "user:roles:";
|
||||
|
||||
/**
|
||||
* 角色对应的权限集合 KEY 前缀
|
||||
*/
|
||||
private static final String ROLE_PERMISSIONS_KEY_PREFIX = "role:permissions:";
|
||||
|
||||
/**
|
||||
* 构建角色对应的权限集合 KEY
|
||||
*
|
||||
* @param roleKey 角色 key
|
||||
* @return 角色对应的权限集合 KEY
|
||||
*/
|
||||
public static String buildRolePermissionsKey(String roleKey) {
|
||||
return ROLE_PERMISSIONS_KEY_PREFIX + roleKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建用户-角色 KEY
|
||||
*
|
||||
* @param userId 用户 ID
|
||||
* @return 用户-角色 KEY
|
||||
*/
|
||||
public static String buildUserRoleKey(Long userId) {
|
||||
return USER_ROLES_KEY_PREFIX + userId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user