文章目录
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;
}