如何通过代理连接识别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 的书签)的问题。
我们开发了一个通过 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 的书签)的问题。