Spring Cloud Zuul 实现Session共享实践

项目介绍

eureka-server:服务治理中心

zuul-server:路由网关

eureka-client:服务1

eureka-client2:服务2

测试

1、网关服务登陆并将用户信息保存到Session中

2、检查Session是否存入Redis

3、通过网关请求服务1,并从Session中获取用户信息

4、通过网关请求服务2,并从Session中获取用户信息

项目核心代码

zuul-server

1、添加以下依赖,并在启动类Application中添加 @EnableZuulProxy@EnableRedisHttpSession 注解。

<!-- 路由网关Zuul -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- Spring Session 整合 Redis -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
	<version>2.1.5.RELEASE</version>
</dependency>

2、配置application.properties

## 基础配置
server.port=8081
spring.application.name=zuul-server

## Eureka配置
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/

## Zuul配置
# api-a:路由的名称,可自定义
zuul.routes.api-a.path=/api-a/*
zuul.routes.api-a.serviceId=hello-service
zuul.routes.api-a.sensitiveHeaders="*"

zuul.routes.api-b.path=/api-b/*
zuul.routes.api-b.serviceId=hello-service2
zuul.routes.api-b.sensitiveHeaders="*"

## Spring Session配置
spring.session.store-type=redis
spring.session.timeout=PT30M

## Redis配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=root
spring.redis.timeout=PT30M

注意:sensitiveHeaders需要设置为 "*",默认Zuul转发时不携带Cookie等敏感信息,会导致Session不一致。

3、创建登陆状态拦截器 RedisSessionFilter 并配置到 Zuul

/**
 * 登陆状态过滤器
 **/
public class RedisSessionFilter extends ZuulFilter{
    private static Logger logger = LoggerFactory.getLogger(RedisSessionFilter.class);

    @Override
    public String filterType() {
        return "pre"; // 在请求被路由之前执行
    }

    @Override
    public int filterOrder() {
        return 1; // 执行顺序
    }

    @Override
    public boolean shouldFilter() {
        return true; // 该过滤器是否需要被执行
    }

    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        HttpSession session = request.getSession();
        Object userName = session.getAttribute("UserName");
        if (userName!=null){
            context.setSendZuulResponse(true); // 对该请求进行路由
            return null;
        }
        context.setSendZuulResponse(false); // 不对其进行路由
        response401(context.getResponse());
        return null;
    }

    // 用户未登陆
    private void response401(HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            response.getWriter().print(
                    JsonUtils.objToJson(ActionResult.error("用户未登陆")));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
/**
 * Zuul过滤器配置
 **/
@Configuration
public class ZuulFilterConfig {
    @Bean
    public RedisSessionFilter redisSessionFilter(){
        return new RedisSessionFilter();
    }
}

4、创建Controller实现简单用户登陆,并将用户信息存入Session

// 登陆
@RequestMapping(value = "/login")
public ActionResult login(HttpServletRequest request,String name,String password){
   if (password.equals("123") && name.equals("admin")){
        HttpSession session = request.getSession();
        session.setAttribute("UserName",name);
        return ActionResult.ok("登陆成功! SessionId:"+session.getId());
   }else{
        return ActionResult.error("账号密码失败!");
   }
}

eureka-client、eureka-client2

1、添加以下依赖并在启动类Application添加 @EnableRedisHttpSession 注解。

<!-- Spring Session 整合 Redis -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
	<version>2.1.5.RELEASE</version>
</dependency>

2、创建简单Controller获取Session中存储的用户信息

@RequestMapping(name = "/hello")
public ActionResult hello(HttpServletRequest request){
    HttpSession session = request.getSession();
    String userName = (String) session.getAttribute("UserName");
    return ActionResult.ok("eureka-client1! SessionID:"+
                session.getId()+" UserName:"+userName);
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值