如何通过代理连接识别https客户端

How to identify https clients through proxy connection

我们开发了一个通过 http/2 协议服务的企业 NodeJS 应用程序,我们需要通过 IP 地址来识别客户端,因为服务器需要根据他们的 IP 向客户端发送事件(基本上是一些关于 phone 调用)。

我可以通过req.connection.remoteAddress成功获取到客户端IP,但是有一些客户端只能通过我们的代理服务器访问服务器。

我知道 x-forwarded-for header,但这对我们不起作用,因为代理无法修改 ssl 连接中的 http headers。

所以我可以从客户端获取 IP 并发送回服务器,例如,在登录过程中。

但是,如果我没记错的话,浏览器不会向 javascript 提供该信息,因此我们首先需要一种获取该信息的方法。

研究它,我发现的唯一选择是从服务器获取,它可以告诉我从哪里到达它的 IP。

当然,由于代理,我不能通过 https。但是我可以很容易地启用一个http服务来服务客户端IP。

但后来我发现由于 "mixed active content" 问题,浏览器会阻止来自 https-served 页面的 http 连接。

我读到了它,我发现我可以得到“mixed passive content”并且我成功地通过 <img> 下载垃圾数据作为图像文件,但是当我尝试做同样的事情时使用 <object> 元素我再次遇到 "mixed active content" 块问题,即使在 MDN 文档中它说它被认为是 passive.

是否有任何方法可以通过那个(损坏的)<img> 标签读取该数据,或者我是否遗漏了一些东西来使 <object> 元素真正 被动?

任何其他实现我们目标的想法也将受到欢迎。

终于找到了解决办法:

正如我所说,我能够通过放置 <img> 标记来执行 http 请求。

我无法做的是读取下载的数据,无论它是否是实际图像。

...但事实是请求已经发出,url 是我可以事先决定的。

所以我需要做的就是为每个服务的登录屏幕生成一个随机密钥,并且:

  • 记住它与您的 session 数据。
  • 插入一个可能隐藏的 <img> 标记,指向包含该 ID 的某个 http url。

只要您的 http 服务器收到下载该图片的请求,您就可以通过 x-forwarded-for header(相信您的当然是代理)并解析它属于哪个活动session。

当然,你也一定要注意清除密钥,不管使用与否,使用一段时间后,避免内存泄漏甚至被恶意重复使用。

最后注意: 这种方法的唯一缺点是有风险,有一天,浏览器也可能开始阻止 混合被动内容 默认情况下。

出于这个原因,事实上,我选择了双重策略方法。也就是说:除了上面解释的技术之外,我还实现了一个 http 重定向器,它的作用几乎相同:它将所有请求重定向到我们的 https 应用程序的根路由(“/”)。但它是通过一个 POST 请求来实现的,该请求包含一个先前与客户端真实 IP 相关联的密钥。

这样,万一哪天第一种方法失效了,用户无论如何都可以先通过http访问。 ...这实际上就是我们要做的。但是第一种方法在继续工作的同时,可以避免如果用户决定从页面中为页面添加书签(这将导致其 https url 的书签)的问题。