会话共享
- 依赖
<!-- session share -->
<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>
- 配置redis
spring:
redis:
host: localhost
port: 6379
- 配置security
// 注入
private final FindByIndexNameSessionRepository sessionRepository;
@Bean
public SessionRegistry sessionRegistry() {
return new SpringSessionBackedSessionRegistry(sessionRepository);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement() // 开启会话管理
.maximumSessions(1) // 最大同时登陆数
// .and().invalidSessionUrl("invalidSession") // 错误session处理
// 属于SessionManagementFilter重定向
// .expiredUrl("/expired") // 被挤下线的会话过期处理 属于ConcurrentSessionFilter将重定向到expiredUrl
.expiredSessionStrategy( // 过期策略(前后端分离)
event -> {
HttpServletResponse response = event.getResponse();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
String json =
"{\"success\":false,\"message\":\"SESSION_INVALID\",\"code\":401}";
response.getWriter().println(json);
})
.maxSessionsPreventsLogin(true) // 登陆后禁止再次登陆(不允许二次登陆)
// session 共享
.sessionRegistry(sessionRegistry())
;
}
会话次数限制Bug
如果继承 UserDetails 的实体类没有重写 equals 和 hashCode 方法, 或调用了父类的方法 (super), 但父类没重写, 导致比对失败, 可以无限制登陆.
解决办法出处: https://stackoverflow.com/questions/51916715/concurrent-session-management-not-working-i-have-followed-the-documentation-bu
跨域
-
单独: @CrossOrigin(origins=“http://允许的域”) 注解(类、方法)
-
全局:
addCrosMapping
重写WebMvcCofingurerComposite#addCorsMapping 方法来实现 -
全局: 过滤器Filter方案
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
// Cors 配置信息
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("https://www.leetcode.com:8080"); // 允许的域
config.setAllowCredentials(true); // 允许发送 cookie 信息
config.addAllowedMethod("*");
config.addAllowedHeader("*"); // 允许头信息
config.setMaxAge(3600L);
// 添加映射路径, 拦截一切请求
UrlBasedCorsConfigurationSource configSrouce = new UrlBasedCorsConfigurationSource();
configSrouce.registerCorsConfiguration("/**", config);
// 返回新的 CorsFilter
return new CorsFilter(configSrouce);
}
}
Cookie 共享问题 (session共享)
由于浏览器是根据应用的 域名 或 IP地址 储存 Cookie 的 (也就是 sessionId ), 相同域名或 IP地址, 即使端口不同, 相互之间也会干扰, 造成 session共享的问题, 也就是 A 项目的 sessionId 用到了 B 项目上, 导致 B 项目判断 session 不存在.
解决办法也很简单, 使名称也就是 key (JSESSIONID=xxxxx) 不重复就行了.
server.servlet.session.cookie.name=new_name