我在网站A上有一个用户,我需要将他登录到网站B(不在我的控制之下),但不会损害他在网站B上的密码。网站B没有API,这使得它比应该。
我的第一个选择是在网站A上呈现我自己的表格,用户在我的表格中输入他的网站B密码,我以某种方式安全地将他的网站B密码传递给网站B以登录他。这意味着我必须首先通过密码从客户端安全地发送到我的服务器,然后再次从我的服务器安全地传递到最终网站。这就是我猜我必须要做的,但我没有计划如何安全地实现这两个跳,所以我担心我可能会以某种方式暴露用户的密码。
所以我想到了第二个选项,就是将同一个网站B从网站B渲染到我的网站上。但是网站B上的表格是较大页面的一部分,所以可以这样做吗?
这是我想到的两种不同的解决方案。我欢迎他们每个人的答案,并欢迎提出可能更容易的替代第三种方法的答案。
答案 0 :(得分:7)
只要您在自己的网站上使用SSL,就不会有损害用户密码的重大风险(除非您正在进行某种金融交易,请澄清)。
我的建议是,不要复制他们的表格。而是复制该表单生成的HTTP POST。您可以完全以编程方式执行此操作,用户永远不会离开您的站点,但(在大多数情况下)结果将是用户也登录到他们的站点。
如果要处理某种散列字段,请以表格形式(以编程方式)请求其表单页并使用您收到的任何值将返回发送到第二个站点,以便请求验证。他们的服务器不知道请求不是来自浏览器(实际上,如果您愿意,可以将用户代理添加到HTTP头中)。
我已经使用这种方法来对抗Verizon的网站和LinkedIn(两者都是出于合法目的)并且有效。
回顾一下:
了解HTTP POST的结构。
将登录表单添加到您的网站。
在您的代码中处理请求,使其看起来像POST 网站预计。
从您的代码发布到他们的网站。
在您的网站上显示对用户的响应(如果需要), 重定向,无论如何。
答案 1 :(得分:3)
这完全取决于您要发布的服务器如何处理CSRF [跨站点请求伪造],因为这基本上就是您正在做的事情。例如,如果他们使用的是相对较新的Django,那么来自外部服务器的POST请求将默认失败,除非它们包含csrf cookie值。
如果您可以控制要发布的服务器,则可以解决这个问题。
答案 2 :(得分:3)
我会尝试概述一个解决方案,但它可能不正确,甚至不是你想要的,这绝对是不切实际的。
根据我对XSRF的了解,如果目标网站完成了作业,您将无法模仿您域名中的表单提交。
除了目标站点之外,唯一可以访问用户凭据的是浏览器。所以你真正需要做的是成为一个浏览器。这意味着您必须说服用户他可以将您的登录信息提供给其他站点。我不知道你怎么能这样做,我不相信那样的东西。 (另一种选择是欺骗他(网络钓鱼),但这是非法的,我认为你甚至不会考虑它。)
在您设法说服用户向您提供他的数据后,您仍然必须像浏览器一样行事。您必须实现一个系统,用于为每个用户存储cookie,以便在您登录时创建会话。
执行此操作后,您将使用用户的数据登录,但用户不会。因此,您还需要通过您的网站实现用户所需的任何其他操作。
我的建议:
与目标站点联系并设置可用于从站点对用户进行身份验证的协议。有一些非常酷的iframe技术可以做到这一点。阅读这篇文章,获得一份称职的演讲http://softwareas.com/cross-domain-communication-with-iframes。
或者让用户打开一个带有该站点登录页面的弹出窗口。确保弹出窗口显示地址栏。
答案 3 :(得分:2)
我并没有真正得到你想做的事情,如果只是登录网站你可能会做这样的事情:
Mainsite :
<iframe id="logon" src="/logonto-other.html"></iframe>
/ logonto-other.html :
<form onsubmit="top.logon.style.visibility='none';" action="http://other-site.com/login" method="post">
<dl>
<dt><label for="user">Name</label></dt>
<dd><input name="user" />
<dt><label for="pass">Password</label></dt>
<dd><input name="pass" />
</dl>
<?php //code that acquires hash from other site
// Don't know site B so can't write this one yet.
?>
<input type="submit" value="Login" />
</form>
这样用户只会登录到其他网站,你的互动能力仍然有限(或者,我认为,我从未学过同源策略,因为我从未觉得有任何限制我的工作。也许今天的浏览器更严格。
关于“2跳”的事情,您的服务器A上是否有证书和SSL / HTTPS支持?服务器B有这个吗?你认为你可以让用户信任你的密码吗?一个提示是你添加了一个解释情况的段落和用户可以联系站点B的链接,以增加对它们施加OAuth和/或OpenID的压力吗?
即使您的服务器上没有HTTPS,也可以使用JavaScript或Java小程序来加密密码(在网络上的某个地方必须有PGP)。 ,如果浏览器地址栏变为绿色,则用户可以更轻松地决定是否信任您。
想要回答一些问题,我们是否可以知道B站点是什么?你究竟想做什么,也许我们可以一起解决这个问题。
祝你好运。答案 4 :(得分:1)
要将表单与较大的页面隔离,请找到<form>
和</form>
标记,并仅复制它们之间的任何元素。现在将该表单放在您的页面上,其操作仍然指向它在原始网站上指向的URL。密码永远不会通过您的服务器。
答案 5 :(得分:1)
请参阅:Sockets
请注意,您可能希望保持公开诚实的对话,了解您使用网站B做什么,或者您可以liable for civil action。
答案 6 :(得分:0)
您所描述的场景可能很难实现。您面临的主要问题是如何将登录凭据发布到站点B,使得成功登录本身返回的cookie最终在用户的浏览器中并且属于站点B,这样站点B就可以获取它们。用户实际上在那里导航。
有些人建议将表单发布到服务器上的PHP文件中,然后让它从服务器到服务器进行登录。这个解决方案几乎不可行。即使站点B接受您的服务器 - 服务器登录(它可能会,因为您可以伪造任何您想要的浏览器),它将您的网络服务器将获取新的cookie,并且您的会话将与之关联的网络服务器的IP。即使您将cookie返回到浏览器,它也会将其保存到您的站点(站点A),并且在浏览器到达时不会将其提交到站点B,因此用户将保持注销状态B站点。
因此,您在这里唯一能做的就是在您的服务器上托管其网站的登录表单。这意味着您必须向浏览器发送一个表单,该表单的ACTION指向站点B的登录表单。这也意味着无论何时用户单击登录按钮,控件都会转移到站点B:用户将离开您的站点而您将失去他。
第二种方法存在两个主要技术问题:一种是站点B可能具有XSS预防功能,实际上可能会阻止您将内容发布到其登录页面。另一个问题是,如果您的网站使用SSL,浏览器会唠叨您将表单提交到其他网站的大量时间。这些都不是你自己能解决的问题。
唯一干净的解决方案是真正与网站B坐下来并制定一些关于通用身份验证或至少是身份验证API的计划。您可以尝试使用表格交叉解决方案,但您可能会遇到不喜欢的问题。