jm-apis-common pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
</dependency>
jm-user-api bootstrap-dev.yml
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
namespace: f5d53f37-d171-43c7-9b77-01c64eeae769
config:
namespace: f5d53f37-d171-43c7-9b77-01c64eeae769
extension-configs:
- dataId: jm-user-api.yaml
refresh: true
shared-configs:
- dataId: jm-redis.yaml
refresh: true
- dataId: jm-token.yaml
refresh: true
jm-user-api jm-token.yaml
sa-token:
token-name: token
timeout: -1
activity-timeout: -1
is-concurrent: true
is-share: false
token-style: random-32
is-log: true
is-read-head: true
jm-gateway pom.xml
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-reactor-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
jm-gateway RedisConf.java
package com.jm.gateway.conf;
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.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableRedisRepositories
public class RedisConf {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
jm-gateway SaTokenConf.java 网关sa-token配置
package com.jm.gateway.conf;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.router.SaRouterStaff;
import cn.dev33.satoken.stp.StpUtil;
import com.jm.gateway.bean.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
@Slf4j
@Configuration
public class SaTokenConf {
private final RedisTemplate<String, Object> redis;
private final SecureConf secureConf;
@Autowired
public SaTokenConf(RedisTemplate<String, Object> redis, SecureConf secureConf) {
this.redis = redis;
this.secureConf = secureConf;
}
@Bean
public SaReactorFilter getSaReactorFilter() {
return new SaReactorFilter()
.addInclude("/**").addExclude(secureConf.getApiWhiteUris().toArray(new String[0]))
.setAuth(obj -> {
SaRequest request = SaHolder.getRequest();
SaRouterStaff routerStaff = SaRouter.match("/**", "/user/api/open/**", r -> StpUtil.checkLogin());
if (routerStaff.isHit) {
String token = request.getHeader("token");
if (StringUtils.isBlank(token)) {
token = request.getParam("token");
}
}
})
.setError(e -> Result.fail(e.getMessage()))
.setBeforeAuth(o -> this.configCross());
}
private void configCross() {
SaHolder.getResponse()
.setHeader("X-Frame-Options", "SAMEORIGIN")
.setHeader("X-XSS-Protection", "1; mode=block")
.setHeader("X-Content-Type-Options", "nosniff")
.setHeader("Access-Control-Allow-Origin", "*")
.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
.setHeader("Access-Control-Max-Age", "3600")
.setHeader("Access-Control-Allow-Headers", "*");
SaRouter.match(SaHttpMethod.OPTIONS).free(r -> log.warn("--------OPTIONS预检请求,不做处理")).back();
}
}
jm-gateway SecureConf .java 在配置中心配置权限
package com.jm.gateway.conf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
@Component
@ConfigurationProperties(prefix = "secure")
public class SecureConf {
private Long limitIpSecondCount;
private Long limitIpMinuteCount;
private Long limitIpHourCount;
private List<String> ipWhites;
private List<String> ipBlacks;
private List<String> apiWhiteUris;
private List<String> xssBlackUris;
}
完整代码请看项目git地址
https://gitee.com/sunuping/jianmu-example-jdk17.git