SpringBoot整合Redis使用x-auth-tonken实现Session共享

SpringBoot整合Redis使用x-auth-tonken实现Session共享

1、配置pom.xml文件

配置pom.xml文件,引入相关的依赖,如下示例:

        <!-- 引入redis,增加springboot使用redis实现session共享 -->
        <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>

2、配置application.properties文件

本示例为单节点的redis配置,参考如下:

#指定redis实现spring session
spring.session.store-type=redis
# Session 过期时间,单位s
server.servlet.session.timeout=1800

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=123456
spring.redis.database=1
# 防止冲突,指定namespace,这里为应用名称
spring.session.redis.namespace=${spring.application.name}

3、配置启动类

配置我们应用程序的主启动类,添加@EnableRedisHttpSession注解(注意,这个注解可以不用配置),如下示例:

@SpringBootApplication
@EnableRedisHttpSession
public class DavidRedisSessionApplication {

    public static void main(String[] args) {
        SpringApplication.run(DavidRedisSessionApplication.class, args);
    }

}

4、验证

4.1、编写一个Controller类

我们编写一个Controller类,验证session的存储和获取session的内容,如下:

@RestController
@RequestMapping("/test")
public class TestSessionController {

    @RequestMapping("/set")
    public Map<String,Object> setSession(HttpSession session, HttpServletRequest request){
        String name = request.getParameter("name");
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("serverTime",new Date());
        session.setAttribute("name",name);
        return dataMap;
    }

    @RequestMapping("/get")
    public Map<String,Object> getSession(HttpSession session){
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("serverTime",new Date());
        dataMap.put("name",session.getAttribute("name"));
        return dataMap;
    }

}

4.2、使用postman发送请求

我们使用postman分别发送请求,设置会话信息并获取会话信息

4.2.1、设置会话信息

在这里插入图片描述

4.2.2、获取会话信息

在这里插入图片描述

4.3、通过Redis Desktop Manager查看数据

通过Redis Desktop Manager连接到本地的Redis数据库,查看我们刚刚设置的session数据,如下:

在这里插入图片描述

5、使用x-auth-token代替JSESSIONID

一般来说我们不推荐使用x-auth-token来代替JSESSIONID实现会话的共享,因为会存在跨站安全问题,但是接入的端为APP或者小程序时,有些情况需要则使用x-auth-token 进行会话共享。

具体的思路是:

1、第一次请求时,后台自动生成一个ID串,在响应头中以x-auth-token的方式返回给客户端

2、客户端在后续每次调用时,需要在http请求头中加上x-auth-token来标识会话

SpringBoot 1.x版本默认为我们提供了一个HeaderHttpSessionStrategy来实现此功能,代码如下:

public class HeaderHttpSessionStrategy implements HttpSessionStrategy {
    private String headerName = "x-auth-token";

    public HeaderHttpSessionStrategy() {
    }

    public String getRequestedSessionId(HttpServletRequest request) {
        return request.getHeader(this.headerName);
    }

    public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) {
        response.setHeader(this.headerName, session.getId());
    }

    public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader(this.headerName, "");
    }

    public void setHeaderName(String headerName) {
        Assert.notNull(headerName, "headerName cannot be null");
        this.headerName = headerName;
    }
}

SpringBoot 2.x版本 提供的是HeaderHttpSessionIdResolver实现,代码如下:

package org.springframework.session.web.http;

import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HeaderHttpSessionIdResolver implements HttpSessionIdResolver {
    private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token";
    private static final String HEADER_AUTHENTICATION_INFO = "Authentication-Info";
    private final String headerName;

    public static HeaderHttpSessionIdResolver xAuthToken() {
        return new HeaderHttpSessionIdResolver("X-Auth-Token");
    }

    public static HeaderHttpSessionIdResolver authenticationInfo() {
        return new HeaderHttpSessionIdResolver("Authentication-Info");
    }

    public HeaderHttpSessionIdResolver(String headerName) {
        if (headerName == null) {
            throw new IllegalArgumentException("headerName cannot be null");
        } else {
            this.headerName = headerName;
        }
    }

    public List<String> resolveSessionIds(HttpServletRequest request) {
        String headerValue = request.getHeader(this.headerName);
        return headerValue != null ? Collections.singletonList(headerValue) : Collections.emptyList();
    }

    public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
        response.setHeader(this.headerName, sessionId);
    }

    public void expireSession(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader(this.headerName, "");
    }
}

5.1、配置HttpSessionStrategy

我们只需要在启动类或者配置类中,增加如下的配置即可:

5.1.1、 1.x版本的SpringBoot
	@Bean
	public HttpSessionStrategy httpSessionStrategy() {
		return new HeaderHttpSessionStrategy();
	}
5.1.2、 2.x版本的SpringBoot
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
    return new HeaderHttpSessionIdResolver("x-auth-token");
}
5.1.3、 测试验证

我们用postman进行测试验证,可以看到在第一次设置Session的时候,会在http返回头中多一个字段:x-auth-token,如下:

在这里插入图片描述

我们在获取的时候需要带上,如下:

在这里插入图片描述

2023-09-07追加x-auth-token放到cookie中

/**
     *
     * 设置session头使用x-auth-token
     *
     * @return
     */
    @Bean
    public CookieHttpSessionIdResolver httpSessionStrategy() {
        // "x-auth-token"
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setCookieName("x-auth-token");
        defaultCookieSerializer.setCookiePath("/");
        CookieHttpSessionIdResolver cookieHttpSessionIdResolver = new CookieHttpSessionIdResolver();
        cookieHttpSessionIdResolver.setCookieSerializer(defaultCookieSerializer);
        return cookieHttpSessionIdResolver;
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_David

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值