【问题标题】:Indy HTTP Client: sessions like in web browserIndy HTTP 客户端:像在 Web 浏览器中一样的会话
【发布时间】:2011-04-06 23:05:56
【问题描述】:

我正在制作一个用于在网站上注册的程序。
为此,我使用 C++Builder 和 Indy (TIdHTTP)。

它是如何工作的:

  • 程序通过GET方式接收注册页面,并从中提取验证码图片地址;
  • 下载验证码 (GET) 并将其提供给用户;
  • 将用户提供的数据以 POST 请求的形式发送到网站。

问题:验证码总是不正确。这一定是因为在这三个网站调用之间的某个地方,验证码挑战发生了变化。

为了防止这种情况,这些请求必须以某种方式连接
所以我认为,这里需要某种sessions 支持...

请告诉我如何在 Delphi 或 C++Builder 中实现这一点

编辑:

感谢Runner,我发现 Session ID 存储在 cookie 中

【问题讨论】:

  • 请提供有关以下内容的更多信息。 1 - CAPTCHA 系统如何向呼叫者提供 ID。此 cookie、返回页面中的表单字段、唯一 URL... 2 - 此 CAPTCHA 系统是第三方吗?它是用哪种语言编写的等等...我仍然相信您只是没有在 POST 请求中将 ID 传回。

标签: delphi session get c++builder indy


【解决方案1】:

对我来说,顺序似乎是正确的。只需检查在发布 CAPTCHA 答案时,您是否提供了 ID 以告知这是哪个 CAPTCHA。

在我看来,您的 POST 似乎未被识别为特定请求。换句话说,您可能没有将响应与特定用户相关联。当您第一次调用 GET 并从服务器取回 CAPTCHA 时,服务器必须为您提供返回的 CAPTCHA 的唯一 ID。这可以是唯一的 URL、cookie、嵌入在返回的 HTML 中的字段等...

这是我根据你的描述的猜测。

编辑:

我有更多信息。它显然是一个 PHP 服务器。来自“BlaXpirit”提供的页面:

访问您网站的访问者是 分配了一个唯一的id,所谓 会话 ID。这要么存储在一个 用户端的 cookie 或者是 在 URL 中传播。

所以,如果 ID 在 cookie 中,那么我猜你没有将 cookie 发回。你是这里的中间人,事情是这样的。

  1. 您对 CAPTCHA 服务器进行了 GET。
  2. 您会返回包含 cookie 的响应
  3. 您将验证码发送回客户端,但不要发送 cookie。

您应该将 cookie 发送给客户端,然后返回 CAPTCHA 服务器,或者拥有自己的会话管理,存储 CAPTCHA cookie,在客户端发送响应时识别客户端并将响应的 cookie 发送回验证码服务器。

【讨论】:

  • 没有办法“提供ID”,它保存在网站的$_SESSION数据中
  • 验证码系统必须知道由谁来处理答案。用户如何将该信息传递给 CAPTCHA 系统。在 POST 隐藏字段中,在 cookie 数据中,还有什么……? CAPTCHA 系统必须在第一次 GET 后通知您此类 ID。
  • @BlaXpirit; HTTP 是一种无状态协议。为了记住每个客户端,服务器需要客户端向服务器提供一些唯一的标识。为此,客户端应在 URL 中发送该 ID,或通过 cookie 或 HTML 表单的隐藏字段。所以你应该首先说明你的服务器使用的是什么会话管理机制。
  • 如果你使用 Indy,那么你有两个类,ARequestInfo: TIdHTTPRequestInfo 和 AResponseInfo: TIdHTTPResponseInfo。里面有 Cookies 属性,它指向 cookie 的冷却。只是谷歌的解决方案。
  • @BlaXpirit:阅读您链接到的页面:“访问您网站的访问者被分配了一个唯一 ID,即所谓的会话 ID。这要么存储在用户端的 cookie 中,要么在 URL 中传播。”所以问题是 - 您的服务器如何将 ID 传播给客户端?它是通过 cookie 还是通过 URL 进行的?这是一个重要的区别。没有它,我们就无法告诉您如何使您的 Indy 代码正确地使用 ID。
【解决方案2】:

如果服务器在 cookie 中发送 PHP 会话 ID,请确保您使用的是最新版本的 Indy。 Indy 10 的 cookie 处理已经中断了一段时间,但我最近检查了 Indy 的 cookie 管理的新代码以解决很多问题。

如果服务器在注册表单的隐藏字段中发送 PHP 会话 ID,那么您需要确保在发送回的 POST 数据中包含该 ID。

【讨论】:

  • 那么我建议尽可能升级到最新的 Indy 10 快照。除此之外,您还没有说服务器将其会话 ID 传递给您的客户端的准确程度。即使 PHP 将其会话 ID 存储在其 $_SESSION 数据中,该 ID 仍然必须往返于客户端并返回,以便服务器可以在后续请求中匹配它。如果您不愿意或无法告诉我们该 ID 是如何在 HTTP 层传递的,那么您必须向我们提供注册页面的 URL,以便我们自己查看...
  • ...只有这样我们才能告诉您如何让您的 Indy 代码正确使用它。
  • 请在表单设计器中右键单击 TIdHTTP 以查看您安装了哪个版本的 Indy。然后使用数据包嗅探器,例如 Wireshark 或 Indy 自己的 TIdLog... 组件,来验证 PHP 是否真的在发送 cookie,并且 TIdHTTP 没有将其发回。然后请发布实际的 HTTP 'Set-Cookie' 标头和所涉及的 PHP URL,我会将它与 Indy 的 cookie 逻辑进行比较,看看它出了什么问题(我在 Indy 开发团队中)。
  • 您写道您认为您正在使用 Indy 9。我告诉您如何验证(在表单设计器中右键单击 TIdHTTP)。至于 cookie,TIdHTTP 会自动为您处理 cookie(确保 TIdHTTP.AllowCookies 属性设置为 True)。但是,如果 TIdHTTP 没有正确地将 cookie 发送回服务器,那么这可能是 Indy 的 cookie 处理中的一个错误。这就是为什么我要求您从数据包嗅探器中捕获原始数据,以便验证 Indy 的逻辑。
  • 那么你至少需要升级到最新的 Indy 9.0.50 快照,如果不是最新的 Indy 10.5.8 快照(我推荐 Indy 10,但这是对 Indy 8 的重大升级- Indy 9 将更加向后兼容)。
【解决方案3】:

使用 IdCookieHandler 并将其链接到 IdHTTP 对象。然后所有的 cookie / 会话管理工作将由 Indy 自动完成

如果您想使用真正的会话支持和网络自动化(包括注册),这是最快速、最简洁的解决方案。

【讨论】:

  • Indy 中没有 IdCookieHandler 组件。正确的名称是 TIdCookieManager,如果您没有明确提供自己的名称,TIdHTTP 已经在内部创建了它的实例。
  • 对不起,我把名字弄混了。在使用 Delphi 7 和 TIdHTTP 时,我必须显式创建一个并将 TIdHTTP 链接到它。不知道新版本......
  • 好像没有这个组件
  • 您不需要创建自己的 TIdCookieManager 组件。如果 TIdHTTP.AllowCookies 属性为真,则 TIdHTTP 会自动创建一个。 @BlaXpirit:是的,有这样一个组件。
【解决方案4】:

让我猜猜,嗯...我打赌你注册了雅虎 :) 无论如何,对于大多数流行的邮件提供商来说,这并不容易,有一些 javascripts 可以防止自动注册。这些脚本可以动态生成 cookie 或 POST 字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多