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

1. 背景

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

一个用来登录的 登录成功后会设置cookie 后续请求就会使用该cookie (cookie的键值就是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 表示 允许在跨站点请求中发送
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
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.mfbz.cn/a/109223.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode热题100 旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9…

2022年06月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 运行下列程序,输出的结果是?( ) tup1 (苏炳添, 谷爱凌, 北京冬奥会, …

VSCode编写Unity代码自动补全配置

1.下载并安装.NET 7.0(C#插件需要)和.NET Framework 4.7.1(Unity需要) .NET 7.0下载链接:https://dotnet.microsoft.com/en-us/download .NET Framework 4.7.1下载链接:https://dotnet.microsoft.com/en-…

cmd基本命令

一、cmd黑框是什么 cmd 是 Windows 命令提示符(cmd.exe)是 Windows NT 及以后的 Windows 系统下的一个用于运行 Windows 控制面板程序或某些 DOS 程序的shell程序;或在 Windows CE 下只用于运行控制面板程序的外壳程序。 二、打开步骤 wind…

H5游戏源码分享-命悬一线

H5游戏源码分享-命悬一线 在合适的时机跳下绳子&#xff0c;能安全站到木桩上&#xff0c;就通过。 游戏源码 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name&…

多线程---阻塞队列+生产者消费者模型

文章目录 阻塞队列自己实现一个阻塞队列&#xff08;三步&#xff09;标准库中的阻塞队列使用阻塞队列的优势 生产者消费者模型 阻塞队列 队列&#xff08;Queue&#xff09;是我们熟悉的一个数据结构&#xff0c;它是“先进先出”的。但是并不是所有的队列都是“先进先出”的…

RocketMq源码分析(八)--消息消费流程

文章目录 一、消息消费实现二、消息消费过程1、消息拉取2、消息消费1&#xff09;提交消费请求2&#xff09;消费消息 一、消息消费实现 消息消费有2种实现&#xff0c;分别为&#xff1a;并发消费实现&#xff08;ConsumeMessageConcurrentlyService&#xff09;和顺序消费实现…

pre-existing shared memory block

发生原因: 1.服务器cpu、内存进行扩容 2.非正常关闭,导致任在占用共享内存段 解决方案: 根据shmid进行关闭 ipcs -mipcrm -m xxx

Kotlin协程核心理解

一、协程是什么&#xff1f; 1.1 基本概念的理解 我们知道JVM中的线程的实现是依赖其运行的操作系统决定的&#xff0c;JVM只是在上层进行了API的封装&#xff0c;包含常见的有线程的启动方法&#xff0c;状态的管理&#xff0c;比如&#xff1a;Java中抽象出了6种状态&#x…

windows8080端口占用

查看端口占用 netstat -ano | findstr “8080”查看占用进程 tasklist | findstr “4664”关闭占用进程 taskkill /f /t /im httpd.exe

读图数据库实战笔记03_遍历

1. Gremlin Server只将数据存储在内存中 1.1. 如果停止Gremlin Server&#xff0c;将丢失数据库里的所有数据 2. 概念 2.1. 遍历&#xff08;动词&#xff09; 2.1.1. 当在图数据库中导航时&#xff0c;从顶点到边或从边到顶点的移动过程 2.1.2. 类似于在关系数据库中的查…

操作系统 --- 存储器管理

一、简答题 1.存储器管理的基本任务&#xff0c;是为多道程序的并发执行提供良好的存储器环境。请问好的存储器环境”应包含哪几个方面&#xff1f; 答&#xff1a; 2.内存保护是否可以完全由软件实现&#xff1f;为什么&#xff1f; 答&#xff1a;内存保护的主要任务是确保每…

C语言_断言assert详解

一、assert定义 assert() 的用法像是一种"契约式编程"&#xff0c;在我的理解中&#xff0c;其表达的意思就是&#xff0c;程序在我的假设条件下&#xff0c;能够正常良好的运作&#xff0c;其实就相当于一个 if 语句&#xff1a; if(假设成立) {程序正常运行&…

用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程

&#x1f9f8;注&#xff1a;不要看我的文件多&#xff0c;那是我的其他项目&#xff0c;这个项目所用的文件我会全部用红框框起来&#xff0c;没框的部分不用管&#xff0c;前端两个文件&#xff0c;后端一个文件 &#x1f4dc; 目录 首先&#xff0c;定义前后端交互接口 然…

强化学习中值函数应用示例

一、Gridworld Gridworld是一个用于教授强化学习概念的简化的电子游戏环境。它具有一个简单的二维网格&#xff0c;智能体可以在其中执行动作并获得奖励。这个环境是有限的&#xff0c;因为它有一个明确的开始和结束状态&#xff0c;以及一组确定的动作和奖励。 在Gridworld中&…

use renv with this project create a git repository

目录 1-create a git repository 2-Use renv with this project 今天在使用Rstudio过程中&#xff0c;发现有下面两个新选项&#xff08;1&#xff09;create a git repository (2) Use renv with this project. 选中这两个选项后&#xff0c;创建新项目&#xff0c;在项目目…

NEFU数字图像处理(三)图像分割

一、图像分割的基本概念 1.1专有名词 前景和背景 在图像分割中&#xff0c;我们通常需要将图像分为前景和背景两个部分。前景是指图像中我们感兴趣、要分割出来的部分&#xff0c;背景是指和前景不相关的部分。例如&#xff0c;对于一张人物照片&#xff0c;人物就是前景&…

目标检测算法改进系列之添加EIOU,SIOU,AlphaIOU,FocalEIOU等

YOLOv8添加EIoU,SIoU,AlphaIoU,FocalEIoU,Wise-IoU等 yolov8中box_iou其默认用的是CIoU&#xff0c;其中代码还带有GIoU&#xff0c;DIoU&#xff0c;文件路径&#xff1a;ultralytics/yolo/utils/metrics.py&#xff0c;函数名为&#xff1a;bbox_iou 原始代码 def bbox_i…

故障诊断模型 | Maltab实现LSTM长短期记忆神经网络故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现LSTM长短期记忆神经网络故障诊断 模型描述 长短记忆神经网络——通常称作LSTM,是一种特殊的RNN,能够学习长的依赖关系。 他们由Hochreiter&Schmidhuber引入,并被许多人进行了…

2023 年值得关注的国外网络安全初创公司

网络安全初创公司试图解决的问题往往有点超前于主流。他们可以比大多数老牌公司更快地填补空白或新兴需求。初创公司通常可以更快地创新&#xff0c;因为它们不受安装基础的限制。 当然&#xff0c;缺点是初创公司往往缺乏资源和成熟度。公司致力于初创公司的产品或平台是有风…
最新文章