gateway 是webflux 技术实现的所以 httpsession技术在这里不能使用,spring使用了EnableRedisWebSession 来对WebFlux的支持,但是出现一个问题,就是gateway的WebSession和各个服务之间的httpsession的数据是不一致的
所以不能在gateway 这里使用 session技术和 下级的服务进行相关的操作,这里就只能使用token技术,实现如下:
pom文件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.1.RELEASE</version> </dependency> <!--这里boot必须是2.2.2否则不能发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--redis使用--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
配置文件如下:
server:
port: 8770
spring:
redis:
host: localhost
port: 6379
database: 1
lettuce:
pool:
max-active: 8
max-idle: 8
max-wait: -1ms
min-idle: 1
application:
name: gatewayone #nacosorder
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true # 让gateway可以发现nacos中的微服务
routes:
- id: gateway # 这里的id随意但是不能重名
uri: lb://nacosserver #nacosserver NACOSSERVER
#uri: http://localhost:8762
predicates:
- Path=/get/**
- Method=Get,Post
#- Cookie=DOGE,throwable
#- Header=accessToken,Doge
filters:
- StripPrefix=1
#- SaveSession
- id: gatewayone
#uri: http://localhost:8763
uri: lb://nacosorder
predicates:
- Path=/gea/** # 当这里- Path=/gea/ 有值得时候gea 代表服务器,所以filters: - StripPrefix=1 必须要写,否则不能发现
- Method=Get,Post
filters:
- StripPrefix=1
#- SaveSession
过滤的类如下:
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Qualifier("redisTemplate")
@Autowired
private RedisTemplate template;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//下面是token的使用
log.info("=========Come in MyLogGateWayFilter: " + new Date() + "==========");
//String token = exchange.getRequest().getQueryParams().getFirst("token");
String token = exchange.getRequest().getHeaders().getFirst("token");
template.opsForValue().set("token", token);
if (token == null) {
log.info("==token为null,非法用户========");
exchange.getResponse().setComplete();
}
// 成功
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("this is a post filter2");
}));
}
@Override
public int getOrder() {
return 0;
}
}
这样的代码,在下级的服务是可以接受到token的正确的数据的,代码如下:
@RestController
@Slf4j
public class TestController1 {
@Qualifier("redisTemplate")
@Autowired
private RedisTemplate template;
@GetMapping("/get10")
public String getname(HttpServletRequest request, Model model) {
//HttpSession session = request.getSession();
Map<String, String> map = getHeadersInfo(request);
String id = map.get("token");
log.info(id + "---------------------------");
String id1 = template.opsForValue().get("token:").toString();
if (id.equals(id1)) {
log.info(id1 + "---------------");
}
return "success";
}
public Map<String, String> getHeadersInfo(HttpServletRequest request) {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}
欢迎批评指正!!

由于Gateway基于WebFlux技术,不支持HttpSession,Spring通过EnableRedisWebSession提供WebFlux支持。然而,Gateway与下游服务的Session数据不一致,导致无法直接使用Session技术。解决方案是采用Token技术,通过在POM文件、配置文件中设定过滤器,并在下游服务中正确接收Token数据。此方案有待批评和改进。

2284

被折叠的 条评论
为什么被折叠?



