我做了一个网站,让用户可以创建自己的小部件,并把它们放在自己的网站上。我希望这些网站的用户能够使用Twitter、Facebook和Google登录到这些小部件。我已经完成了99%的流程,但剩下的1%是我的绊脚石。我实现的流程如下:
1.用户在我的站点(mysite.com)上创建小部件
1.用户在自己的网站(example.com)上放置一些javascript来嵌入小部件
1.微件的用户单击“使用Twitter登录”
1.将打开一个新窗口(使用window.open),加载mysite.com/auth/twitter,通过www.example.com上的oAuth流重定向它们twitter.com
1.如果一切正常,用户将在新窗口中被重定向回mysite.com/auth/twitter/callback,我将用户的详细信息存储在mysite.com上的数据库中。
此时,新创建的用户ID应该被传递回嵌入小部件的主窗口。但是,据我所知,没有办法这样做,因为新窗口中的window.opener
为空(由于发生了重定向)。我也没有从主窗口到新窗口的引用,也是由于重定向。
我试过从新窗口到主窗口的window.postMessage
,直接从主窗口访问新窗口中的函数和变量,但都没有效果。似乎没有办法从两个窗口中引用任何数据或属性。
是否还有其他方法可以尝试,或者我是否必须在没有新窗口的情况下以某种方式实现流程?
如果重要的话,mysite.com是在Laravel中构建的,社交身份验证过程使用Socialite。
任何帮助都是感激不尽的!
4条答案
按热度按时间pgccezyw1#
我已经尝试了从新窗口到主窗口的
window.postMessage
postMessage
可以跨域工作,但在这种情况下,必须指定第二个参数(targetOrigin
)。1dkrff032#
考虑到您对如何嵌入小工具的说明,您在所看到的通信选项方面受到了相当大的限制。
由于您的子窗口现在没有办法与父窗口通信,没有window.opener引用并且在不同的域中,您可以依赖父窗口并让它跟踪子窗口的进度,如下面所建议的:https://stackoverflow.com/a/18804255/18706075
另外,不要坚持使用iframe方法,您还可以添加一个在www.example.com上打开的不可见iframemysite.com。这样,最终出现在mysite.com上的弹出窗口有许多选项,可以使数据对同一域上的iframe可用,并且访客iframe可以像我最初建议的那样轻松地与主机窗口通信:
主机侦听
message
事件访客iframe通知主机。
hrysbysz3#
我找不到一个“合适”的方法来完成这个任务,所以我最后做的是生成一个唯一的代码并将其传递给新窗口。这个代码被存储在我的数据库中,并在oAuth过程完成后用用户的ID更新。主窗口使用setInterval每隔几秒钟对照唯一的代码检查用户ID的存在。
y3bcpkx14#
弹出窗口和IFRAME重定向
我会看一下oidc-client库,它曾经做过类似的事情。请看PopupWindow中的代码,以及在重定向之前使用命名窗口对象,然后在响应中使用命名窗口对象的方式。OAuth
state
参数用于关联请求和响应:如果你看一下
IFrameWindow
和IFrameNavigator
类,这个库还执行了一些有趣的iframe navigation。使用iframe可以通过你自己的授权服务器来许可,但是由于clickjacking保护,它不会在Google或Twitter上工作。浏览器限制
上述库不活动的原因之一是浏览器对第三方网站内容的限制,这影响了一些浏览器OpenID Connect的行为。
浏览器将以敌对的方式对待您的小部件,他们将对试图跨站点跟踪用户的第三方广告应用相同的限制。
特别是,如果您的小工具通过调用www.example.com获取数据mysite.com使用HTTP专用Cookie,这将被视为第三方Cookie,并被浏览器丢弃。访问令牌可以工作,但它们并不被视为浏览器当前的最佳安全实践。
主窗口重定向
如果你不能让弹出窗口工作,考虑在主窗口上重定向,从浏览器限制的Angular 来看,这将是最好的工作方式。主窗口重定向作为一个用户手势,这样来自谷歌等的任何登录cookie都不会被丢弃。你的流程可能是这样工作的,尽管它需要一个基于访问令牌的设计:
从用户体验的Angular 来看,用户最初登录到主应用,然后再次登录到作为独立提供者的小部件。对主机应用的影响有点像刷新页面,它已经可以科普了。
未来
FedCM计划的目标是以一种面向未来的方式解决这种类型的跨域浏览器身份问题。它不会在短期内准备好,但值得阅读他们的文档,以确定您自己的解决方案的潜在问题。