springboot web项目中 Set-Cookie 失败 办法

news/2024/5/18 14:12:23 标签: java, session, cookie

1. 背景

目前有个项目 线上环境 使用spring session管理的登录
项目中有两个接口

一个用来登录的 登录成功后会设置cookie 后续请求就会使用该cookiecookie的键值就是session Id 和 登录后的信息 例如菜单,权限等)

一个用来检查是否登录的 根据session id 来判断是否登录 没有登录信息的 直接返回未登录

调用登录成功后 发现Set-Cookie 出现响应头中 但是 调用检查接口发现还是还是未登录

如下图 模拟登录接口 响应中正确返回了 session
在这里插入图片描述
但是检查登录却未将 模拟登陆返回的接口携带上 导致登录校验失败
在这里插入图片描述

2. 问题排查

刚开始怀疑两次请求的session id 不一致导致无法使用 模拟登录返回的cookie 但是在测试环境时 可以校验登录接口正常使用 模拟登陆返回的session

模拟登录的接口
在这里插入图片描述
验证登录的接口
在这里插入图片描述
那问题好像不是session不一致的问题。
因为目前使用spring-session来管理session 如果登录成功后 会将session id 以及登录信息 设置到cookie 同时存入到浏览器 应用的 cookie中 同时会将session 存入到 redis中 其他的接口就会携带

那目前设置没问题 那登录成功后是否 将session 存入到到浏览器应用的cookie 直接去检查 发现没有设置上

在这里插入图片描述
这里发现 模拟登录成功后 并没有将session 存入到 浏览器应用的cookie

那么问题就变成了 为什么 没有将session 存入到 浏览器应用的cookie

接下来就是一步步的修改
首先可以明确的是 页面部署在A域名 接口部署在B域名 这种请求肯定是跨域的 所以我们要在接口的NGINX中添加 跨域配置

#在指定的接口路径中才添加
location /xxxx/ {
        add_header 'Access-Control-Allow-Origin' 'xxx';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods'  '*';
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        #代理的配置 这个是虚拟网关的配置 每个项目不一定相同
        proxy_pass    http://gateway;
    }
  • 修改过程中 首先将登录接口中设置cookie 时增加sameSite 参数 并设置值为None 表示 允许在跨站点请求中发送
java">public static void setCookie(HttpServletResponse response, String cookieName, String value, int maxAgeExpiry) {
    //设置cookie 默认7天
    ResponseCookie cookie = ResponseCookie.from(cookieName, value)
            .httpOnly(true)		// 禁止js读取
            .secure(true)		// 在http下也传输
            .path("/")			// path
            .maxAge(maxAgeExpiry)
            // 新增加的部分 允许在跨站点请求中发送
            .sameSite("None")
            .build()
            ;

    // 设置Cookie Header
    response.setHeader(HttpHeaders.SET_COOKIE, cookie.toString());
    log.info("设置cookie完成,{}: {}", cookieName, cookie);
}
  • 其次在前端 vue的页面调用接口时增加 使用凭证参数 由于使用的时 vue的 axios 请求框架 直接在项目中增加 配置即可 axios.defaults.withCredentials = true;
    其他的方式 添加方式如下
使用vue.resource发送请求时配置如下:
main.js中 Vue.http.options.xhr = { withCredentials: true }
 
 
使用vue.axios发送请求时配置如下:
axios.defaults.withCredentials = true;
 
 
jquery请求带上 xhrFields: {withCredentials: true}, crossDomain: true;
$.ajax({
type: "post",
url: "",
xhrFields: {withCredentials: true},
crossDomain: true,
data: {username:$("#username").val()},
dataType: "json",
success: function(data){ }
});
  • 最后在接口的NGINX配置中同样添加使用凭证参数
add_header 'Access-Control-Allow-Credentials' 'true';

本来以为添加完 应该可以正常请求了 但是 比之前错误更明显了 接口都无法调用了

在这里插入图片描述
结果一看前端页面的控制台 看到如下错误 更有点百思不得其解
Access to XMLHttpRequest at ‘https://xxx/checkAuthorityUpdate’ from origin ‘https://xxx’ has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

居然提示请求头不被允许 但是我的接口 nginx配置

add_header 'Access-Control-Allow-Headers '*';

这个配置意思 应该是允许所有的请求头吧 但是查询了下,看下ai的解释

这个错误提示是因为在进行跨域请求时,浏览器在发送实际请求之前会先发送一个预检请求(OPTIONS请求),这个请求包含了实际请求的所有信息,包括请求头。服务器在接收到这个预检请求后,需要返回一个响应,告诉浏览器哪些请求头是允许的。

在你的配置中,add_header ‘Access-Control-Allow-Headers’ ‘*’;设置的是允许所有请求头,但是浏览器在发送实际请求时,可能只发送了部分请求头,所以服务器需要明确指定允许哪些请求头。

你可以通过add_header ‘Access-Control-Allow-Headers’ ‘Content-Type, Authorization’;来指定允许的请求头为 “Content-Type” 和 “Authorization”。这样,浏览器在发送实际请求时,只有这两个请求头会被发送,服务器在接收到这个请求后,也会只检查这两个请求头,就不会出现这个错误了。

所以我们再次修改请求的配置

add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Accept-Language';

然后就大家都欢喜,校验登录的接口 也可以正常使用模拟登录的session ,模拟登录的session也存入到了应用的cookie


突然在测试某个功能 更新接口 居然提示跨域请求 一看控制台发现 put 方法不被允许 报错详细如下
access to XMLHttpRequest at ‘https://xxx/updateAuditResult’ from origin 'https://xxx has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

接口中的nginx配置

add_header 'Access-Control-Allow-Methods'  '*';

难道又是不允许* 我们改成具体的尝试下看看
修改为具体的method如下

add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE';

果然可以了,至此 set-cookie 问题 解决完成

最后来汇总下解决办法

  1. 接口的nginx 跨域配置 例如 headers和 method 中的* 配置修改为具体的
#xx为接口前缀 请注意配置 如果没有前缀可以放在 / 下
location /xxx/ {
        add_header 'Access-Control-Allow-Origin' 'xxx';
        add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Accept-Language';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE';
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_pass    http://gateway;
    }
  1. 接口中设置cookies的方法 增加 samsite属性 且 属性值为None
java">public static void setCookie(HttpServletResponse response, String cookieName, String value, int maxAgeExpiry) {
    //设置cookie 默认7天
    ResponseCookie cookie = ResponseCookie.from(cookieName, value)
            .httpOnly(true)		// 禁止js读取
            .secure(true)		// 在http下也传输
            .path("/")			// path
            .maxAge(maxAgeExpiry)
            // 新增加的部分 允许在跨站点请求中发送
            .sameSite("None")
            .build()
            ;

    // 设置Cookie Header
    response.setHeader(HttpHeaders.SET_COOKIE, cookie.toString());
    log.info("设置cookie完成,{}: {}", cookieName, cookie);
}
  1. 在前端 vue的页面调用接口时增加 使用凭证参数 由于使用的时 vue的 axios 请求框架 直接在项目中增加 配置即可 axios.defaults.withCredentials = true;
    其他的方式 添加方式如下
使用vue.resource发送请求时配置如下:
main.js中 Vue.http.options.xhr = { withCredentials: true }
 
 
使用vue.axios发送请求时配置如下:
axios.defaults.withCredentials = true;
 
 
jquery请求带上 xhrFields: {withCredentials: true}, crossDomain: true;
$.ajax({
type: "post",
url: "",
xhrFields: {withCredentials: true},
crossDomain: true,
data: {username:$("#username").val()},
dataType: "json",
success: function(data){ }
});

另外 登录成功session 不能生效问题有很多种 包括但不仅限于 如下

  • sessionID 不同问题 前后两个请求的session不同 请注意判断是否 是真的不一致 (例如说 我在登录接口中 将session设置成功 并成功保存到了应用的cookie中 然后在校验登录接口传入的sessionId 却是另一个 这种就属于 sessionID 不一致的 )
    解决: 这种问题不是很好找 需要排查是代码问题 还是使用的框架 问题 还是 接口NGINX配置问题
  • set-cookie 失效 参考文中解决办法
  • 登录请求和校验请求 cookie设置的domin 和 校验请求的domin不同 这种也会导致检验请求 无法使用 登录请求设置的 cookie 不过这种通常出现在 第三方授权中
    在这里插入图片描述
  • nginx配置的 Access-Control-Allow-Origin 和实际的 跨域地址不同 这个在页面控制台会报错 这个修改办法 将NGINX配置修改为和实际请求的地址一样即可

Access to XMLHttpRequest at ‘https://xxx/checkAuthorityUpdate’ from origin ‘https://xxx:8068’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The ‘Access-Control-Allow-Origin’ header has a value ‘https://xxx’ that is not equal to the supplied origin

  • 等等

god day ! ! !


http://www.niftyadmin.cn/n/5130518.html

相关文章

UWB室内定位技术

室内定位系统方案中,UWB室内定位技术目前应用较多,得益于UWB室内定位10-30厘米的超高定位精度。 UWB全称是超宽带技术,它是一种无线载波通信技术。 UWB不采用载波,而是利用纳秒至微微秒级的非正弦波窄脉冲传输数据。 目前根据使用…

【QT开发(17)】2023-QT 5.14.2实现Android开发

1、简介 搭建Qt For Android开发环境需要安装的软件有: JAVA SDK (jdk 有apt install 安装) Android SDK Android NDKQT官网的介绍: Different Qt versions depend on different NDK versions, as listed below: Qt versionNDK…

讯飞星火大模型V3.0 WebApi使用

讯飞星火大模型V3.0 WebApi使用 文档说明:星火认知大模型Web文档 | 讯飞开放平台文档中心 (xfyun.cn) 实现效果 初始化 首先构建一个基础脚手架项目 npm init vuelatest用到如下依赖 "dependencies": {"crypto-js": "^4.2.0",&q…

iOS iGameGuardian修改器检测方案

一直以来,iOS 系统的安全性、稳定性都是其与安卓竞争的主力卖点。这要归功于 iOS 系统独特的闭源生态,应用软件上架会经过严格审核与测试。所以,iOS端的作弊手段,总是在尝试绕过 App Store 的审查。 常见的 iOS 游戏作弊&#xf…

【Python机器学习】零基础掌握IsotonicRegression等渗回归

想要预测一个事件的结果,但因素多且复杂,难以得出精确的预测?在金融、医疗、教育等多个领域,这样的问题是非常普遍的。 假设在医疗领域,医生需要根据多项指标(如年龄、血压、胆固醇水平等)来预测患者是否有心脏病的风险。因为每个指标对结果的影响都可能不同,单一模型…

Error: no matching distribution found for tensorflow-cpu==2.6.*

目录 install_tensorflow()安装过程中遇到的问题 查找解决方案过程中: 解决办法: install_tensorflow()安装过程中遇到的问题 在服务器上安装tensorflow时,遇到了一个报错信息: 在网上找到一个类似的错误(TensorFlow…

统计学习方法 决策树

文章目录 统计学习方法 决策树决策树模型与学习特征选择决策树的生成ID3 算法C4.5 的生成算法 决策树的剪枝CART 算法CART 回归树的生成CART 分类树的生成CART 剪枝 统计学习方法 决策树 阅读李航的《统计学习方法》时,关于决策树的笔记。 决策树模型与学习 决策…

【luckfox】添加压力传感器hx711

文章目录 前言一、参考资料二、电路图三、驱动四、makefile——添加驱动五、dts——使能gpio5.1 参考5.2 改动1—— hx117节点5.3 改动2——引脚节点5.4 已经被定义的引脚5.5 gpio源码 六、改动总结——使能hx711七、验证驱动添加八、编写测试文件8.1 测试代码8.2 配置编译环境…