gateway网关获取分布式session的解决方法
首先我们需要解决spring-session-data-redis的序列化问题,spring-session-data-redis默认使用的是java对象序列化,需要Java对象实现Serializable而且在gateway中取出是乱码的. 所以我们要配置session配置类(类是配置在用户模块不是网关模块)
public class SessionConfig {
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
return serializer;
}
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
gateway中也要记得引入依赖(spring-session-data-redis貌似可以不引入)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
在用户模块我们操作分布式session都是通过HttpServletRequest直接存取即可但在gateway中我们无法使用HttpServletRequest所以我们只能直接从redis中取首先我们要获取sessionid
String cookieValue = exchange.getRequest().getCookies().getFirst(WEB_SESSION_KEY).getValue();
这里有一个坑,cookies中存的sessionid和reids中的格式不同要把sessionid转为base64
String sessionId = new String(Base64.getDecoder().decode(cookieValue));
现在就可以取出redis中的session了我我用RedisTemplate出现了报错使用这里使用了stringRedisTemplate,最后反序列化redis取出的值
String sessionKey =REDIS_SESSION_KEY + sessionId;
// sessionAttr:userLoginState是我这里的写法 具体值取决于你存入的值的名称规则就是sessionAttr:[request.getSession().setAttribute()时指定的名称字段]
String session =(String)stringRedisTemplate.opsForHash().get(sessionKey,"sessionAttr:userLoginState");
Gson gson = new Gson();
User user = gson.fromJson(session, User.class);
gateway完整代码如下:
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.seig.teabackend.common.model.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.Base64;
public class CustomGlobalFilter implements GlobalFilter, Ordered {
private static final String WEB_SESSION_KEY = "SESSION";
private static final String REDIS_SESSION_KEY = "spring:session:sessions:";
private StringRedisTemplate stringRedisTemplate;
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
ServerHttpRequest request = exchange.getRequest();
// 1. 请求日志
String requestPath = request.getPath().value();
requestPath = requestPath.replaceFirst("/api/core", "");
String method = request.getMethod().toString().toLowerCase();
log.info("请求唯一标识:" + request.getId());
log.info("请求路径:" + requestPath);
log.info("请求方法:" + method);
log.info("请求参数:" + request.getQueryParams());
String sourceAddress = request.getLocalAddress().getHostString();
log.info("请求来源地址:" + sourceAddress);
// 获取 Session
User user = getSession(exchange);
// gson.fromJson()
log.info(String.valueOf(user));
return chain.filter(exchange);
}
private User getSession(ServerWebExchange exchange) {
String cookieValue = exchange.getRequest().getCookies().getFirst(WEB_SESSION_KEY).getValue();
String sessionId = new String(Base64.getDecoder().decode(cookieValue));
String sessionKey = REDIS_SESSION_KEY + sessionId;
String session = (String) stringRedisTemplate.opsForHash().get(sessionKey, "sessionAttr:userLoginState");
Gson gson = new Gson();
return gson.fromJson(session, User.class);
}
public int getOrder() {
return 0;
}
}
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
作者分享
有在深圳找前端开发的同学吗?有兴趣的可以来投投我们公司的岗位,技术栈是vue3+ts,应届大概7-8k,自研小公司,期待有鱼友一起来当牛马🤭
链接 https://m.zhipin.com/mpa/html/weijd/weijd-job/766e902b9b6a7e9e1Hxy2tu0F1VV?date8=20241009&sid=tosee_jd_d80c5b1c558d59560nBy29u4F1FS&openWeapp=1&fromSource=2
4
三本大四,绩点倒数,四级没过,学三年JAVA没有6k的工作,学了一个多月转Go拿到深圳7.5k黑奴级别offer,不知道路在何方啊[叹气]#求职#
13
#软件# SaveAction插件在idea更新到2023.x版本后会报错无法使用解决办法,大家要是遇到记得解决,不然idea直接没法用[流泪]
11
准备开学,明天收拾东西做核酸
12
今日任务 复习完成
明天 学新的算法
7
