Javascript Safari在另一台服务器上调用API时拒绝cookie
我的业务有一个React应用程序,它有多个客户。我的架构设置如下: 服务器A-主应用程序服务器,仅服务于React应用程序(url=) 服务器B-业务客户端#1,为其稍微定制的React应用程序提供服务(url=) 服务器C-业务客户端#2,为其稍微定制的React应用程序提供服务(url=) 微服务服务器-运行Java微服务(url=-注意它是服务器a的子域) 服务器A、B和C都在与Microservice服务器进行API调用。API调用使用本机浏览器fetch()调用和这些选项Javascript Safari在另一台服务器上调用API时拒绝cookie,javascript,reactjs,safari,cors,Javascript,Reactjs,Safari,Cors,我的业务有一个React应用程序,它有多个客户。我的架构设置如下: 服务器A-主应用程序服务器,仅服务于React应用程序(url=) 服务器B-业务客户端#1,为其稍微定制的React应用程序提供服务(url=) 服务器C-业务客户端#2,为其稍微定制的React应用程序提供服务(url=) 微服务服务器-运行Java微服务(url=-注意它是服务器a的子域) 服务器A、B和C都在与Microservice服务器进行API调用。API调用使用本机浏览器fetch()调用和这些选项 var op
var options = {
method: "{method}",
mode: "cors",
credentials: "include",
headers: { "Content-Type": "application/json" }
}
服务器响应具有以下标头:
"Access-Control-Allow-Credentials", "true"
并使用微服务的内置
enableCorsForAllOrigins()
现在,这些都可以在Firefox、Chrome、IE和Edge上正常工作。但是,它在服务器B或服务器C的Safari(MacOS或iPhone)上不起作用。它在服务器A的Safari上可以正常工作
API调用的顺序如下
职位
得到
在Safari上,第一次调用成功,但第二次调用失败,出现401错误。试图获取“currentUserId”的会话属性(为null)的微服务抛出401错误。换句话说,Safari没有将cookie发送到服务器。我发现Safari不喜欢API调用指向与客户端服务器不同的URL库。(换句话说,服务器B对服务器A进行API调用)
为了进一步验证这一点,如果用户在服务器B上启动,然后导航到服务器a并进行API调用(例如错误登录),然后返回到服务器B,那么它在Safari上对他们有效。似乎Safari只需要在服务器上交换一个cookie和一个URL,就可以在其他服务器上工作
现在,我的问题…我该如何解决?服务器B和服务器C上Mac Safari和iPhone Safari上的用户无法使用该应用程序,因为他们的会话cookie未发送到服务器。以前有人见过这个吗?有人有解决办法吗?我的第一次尝试是在服务器B上创建一个iframe来加载服务器A的页面,但没有成功
非常感谢 因此,在阅读了上面@str提供的链接,以及这些链接中的链接后,我得出结论,试图使用cookie和会话来实现它是不适用于Safari的。所以我放弃了整个设置,转而使用JWT 因此,我现在的解决方案是:
POSThttps://api.example.net/login
->响应包括服务器生成的带有用户ID的JWT令牌
JavaScript代码现在将此JWT保存到SessionStorage(不是cookie,否则您将遇到与使用Sessions时相同的问题)
设置API调用以始终将JWT令牌作为头传递
"Authorization": "Bearer " + window.sessionStorage.getItem("jwtToken")
然后,使用服务器端库,我可以提取JWT令牌并从中获取用户ID
它可以在Safari上运行,是目前web授权的首选解决方案,所以我建议使用此解决方案。缺点是,将JWT存储在sessionStorage中会让用户遭受XSS攻击。可能是由(以及相关的)原因造成的。“[…]试图使用cookie和会话使其正常工作不会与Safari一起工作”–这是不正确的。当然,饼干与Safari一起使用。但是,根据您的设置和测试的Safari版本,您必须进行一些调整。“it”=跨站点API调用
"Authorization": "Bearer " + window.sessionStorage.getItem("jwtToken")