同源部署自定义sessionId解析器实现一个浏览器同时登录正常使用

news/2024/10/20 20:49:16/

前言

         废话不多说,昨天是实现同源部署返回不同cookie,现在是核心,就是一个浏览器同时登录,客户端、运营端同时正常使用。


一、核心实现

         核心实现实际上就是自定义HttpSessionIdResolver处理sessionid解析,上一篇博文已实现,地址:同源部署自定义sessionId解析器设置不同名称cookie

二、实现双登正常使用

         其实就是自定义的HttpSessionIdResolver的MyHttpSessionIdResolver里的一个resolveSessionIds方法修改下,再前端传参配合下。

1.具体代码

代码如下(示例):

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.easylinkin.security.context.LinkappUserContextProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionIdResolver;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;/*** 自定义SessionId解析器** @author zhengwen*/
@Slf4j
//@Service("httpSessionIdResolver")
public class MyHttpSessionIdResolver implements HttpSessionIdResolver {@Resourceprivate LinkappUserContextProducer linkappUserContextProducer;/*** CookieName默认名称*/public static final String CookieName = "LINKAPP_SESSION_ID";/*** sessionIdName*/private String sessionIdName = CookieName;/*** cookieHttpSessionIdResolver*/private CookieHttpSessionIdResolver cookieHttpSessionIdResolver;/*** 构造函数*/public MyHttpSessionIdResolver() {initCookieHttpSessionIdResolver();}/*** 构造函数** @param sessionIdName sessionIdName*/public MyHttpSessionIdResolver(String sessionIdName) {this.sessionIdName = sessionIdName;initCookieHttpSessionIdResolver();}/*** 初始化cookieHttpSessionIdResolver*/public void initCookieHttpSessionIdResolver() {this.cookieHttpSessionIdResolver = new CookieHttpSessionIdResolver();DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();cookieSerializer.setCookieName(this.sessionIdName);this.cookieHttpSessionIdResolver.setCookieSerializer(cookieSerializer);}@Overridepublic List<String> resolveSessionIds(HttpServletRequest request) {String source = request.getHeader("source");if (StringUtils.isNotBlank(source)) {//这个里面的是核心,就是处理双登后,session会话请求接口时处理对应sessionId返回,让可以进行下一个方法setSessionId()String reqSessionId = request.getHeader(source);return (reqSessionId != null) ? Collections.singletonList(reqSessionId) : Collections.emptyList();} else {// cookieList<String> cookies = cookieHttpSessionIdResolver.resolveSessionIds(request);if (CollUtil.isNotEmpty(cookies)) {return cookies;}// headerString headerValue = request.getHeader(this.sessionIdName);if (StrUtil.isNotBlank(headerValue)) {return Collections.singletonList(headerValue);}// request parameterString sessionId = request.getParameter(this.sessionIdName);return (sessionId != null) ? Collections.singletonList(sessionId) : Collections.emptyList();}}@Overridepublic void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {log.info(CookieName + "={}", sessionId);String source = request.getHeader("source");if (StrUtil.isNotBlank(source)) {this.sessionIdName = source;initCookieHttpSessionIdResolver();response.setHeader(source, sessionId);} else {response.setHeader(this.sessionIdName, sessionId);}this.cookieHttpSessionIdResolver.setSessionId(request, response, sessionId);}@Overridepublic void expireSession(HttpServletRequest request, HttpServletResponse response) {response.setHeader(this.sessionIdName, "");this.cookieHttpSessionIdResolver.setSessionId(request, response, "");}
}

         还需要的配合就是,登录接口从response的Header里取到sessionId,然后后面所有的接口请求都需要携带,例如:
在这里插入图片描述
         source是前端固化的终端标识,我们另一个终端的标识就是admin。
         下面的aep:198ced13-f21d-4ad5-b80b-edf09e983361就是从登录接口返回的response的header里获取的(同样是key代表返回的终端标识,值就是sessionId)
         这个sessionId其实也没有什么好神秘的,也就是跟cookie值是base64加密解密关系。
在这里插入图片描述
         后面其实可以增加sessionId、cookie、终端,3个维度校验,验证传参与终端一致。

总结

  • cookie、session会话关系要清楚理解(理解不清这一切不可为)
  • security安全机制还是很强悍的
             好,就写到这里希望可以帮到大家,uping

http://www.ppmy.cn/news/90022.html

相关文章

提升国际品牌影响力:小企业海外网红营销实战指南

在当今数字化时代&#xff0c;小企业们越来越意识到海外市场的巨大潜力。与此同时&#xff0c;海外网红的崛起也为小企业提供了一个独特的机会&#xff0c;通过与他们合作&#xff0c;迅速拓展国际市场并吸引更多目标受众的关注。然而&#xff0c;对于许多小企业来说&#xff0…

js 常用函数 push()、pop()、shift()、unshift()、slice()、splice() 等

文章目录 1. join() 函数2.push() 函数3. pop() 函数4.shift() 函数5.unshift() 函数6.sort() 函数7. reverse() 函数8. concat() 函数9.slice() 函数10. splice() 函数11. indexOf() & lastIndexOf() 函数 最近对前端一些函数的用法还不是很熟悉&#xff0c;有一些函数容易…

Python函数的定义和调用(通过故事来学习)

从前有个程序猿叫小明&#xff0c;他很懒&#xff0c;不希望在写代码时重复造轮子。于是他想到了"函数"&#xff0c;这样他可以把常用的代码块封装成一个函数&#xff0c;需要的时候直接"调用"就行了。 于是&#xff0c;小明开始学习如何定义和调用函数。…

vscode rust远程开发环境搭建

安装插件rust-analyzer rust-analyzer是个智能补全插件&#xff0c;对于新手来说&#xff0c;非常有用。 vscode提供的rust-analyzer需要GLIBC 2.29&#xff0c;低版本的GLIBC可以安装旧版本的rust-analyzer&#xff0c;新版本的rust-analyzer可以通过源码安装&#xff0c;如下…

一文读懂Vite和Webpack的区别?

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、webpack是什么&#xff1f;二、webpack如何工作&#xff1f;三、Vite是什么&#xff1f;Vite和Webpack的区别&#xff1f; 提示&#xff1a;以下是本篇文章正文…

基于 JMeter 实现 WEB 项目性能测试,环境搭建与测试用例编写

目录 前言&#xff1a; 一、JDK 安装 二、Tomcat 安装 三、Redis 安装 四、数据库安装 五、WEB 项目搭建 六、性能测试项目搭建 七、总结 前言&#xff1a; 性能测试是软件开发中必不可少的一环&#xff0c;它可以帮助开发者提高程序的稳定性&#xff0c;优化性能&…

简单易懂:Ajax入门实例详解(登录功能)

前言&#xff1a;不积跬步无以至千里&#xff0c;不积小流无以成江河&#xff01; 废话不多&#xff0c;以最简练的语言和实例初步了解Ajax&#xff01; 一、Ajax简介 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种基于Web技术的编程实现方式&#xff0c…

anr log打印流程---Java层

前言 本问介绍一下anr之后&#xff0c;系统打印log的流程。加深对anr问题的理解。 anr触发原理分析可以看看这个文章http://gityuan.com/2017/01/01/input-anr/ cpp代码比较多&#xff0c;我选择放弃了。从java层log往后看吧。。。 ANR Log anr触发在native层&#xff0c;…