【问题标题】:How to check connection with a jsp site via IdHTTP如何通过 IdHTTP 检查与 jsp 站点的连接
【发布时间】:2014-09-17 06:14:23
【问题描述】:

我在 Borland Delphi 7 中有一个使用 Indy 组件的程序,我想检查我的登录名和密码是否正确。

这是我当前的代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack,
  IdSSL, IdSSLOpenSSL, IdCookieManager, StrUtils;

type
  TForm1 = class(TForm)
    IdHTTP1: TIdHTTP;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Memo1: TMemo;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    IdCookieManager1: TIdCookieManager;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 post: TStringList;
 poczatek, koniec: integer;
 aStream: TMemoryStream;
 HTML, authToken: string;
 fLogin, fHaslo: string;
begin
 IdHTTP1.HandleRedirects := True;

 fLogin := Edit1.Text;
 fHaslo := Edit2.Text;

 HTML := IdHTTP1.Get('https://e-skok.pl/eskok/login.jsp');
 poczatek := Pos('name="atlassian-token" value="', HTML) +
 Length('name="atl_token" value="');
 koniec := PosEx('"', HTML, poczatek);
 authToken := copy(HTML, poczatek, koniec - poczatek);

 post := TStringList.Create;
 try
   post.Add('atlassian-token=' + authToken);
   post.Add('os_username=' + fLogin);
   post.Add('os_password=' + fHaslo);
 try
   IdHTTP1.Request.ContentType:= 'application/json';
   HTML:= IdHTTP1.Post('https://e-skok.pl/eskok/login.jsp', post);
   Memo1.Text:= HTML;
   Label1.Caption := 'YES';
 except
     if IdHTTP1.ResponseCode = 401 then
       begin
       ShowMessage('Nieprawidłowy login lub hasło.');
       Label1.Caption := 'NO';
       end
      else
      Label1.Caption := ':)';
 end;
 finally
   post.Free;
 end;
end;
end.

问题是当我尝试登录时,程序总是说“是”(这意味着它已连接,即使登录名和/或密码错误)。

通过 IdHTTP 检查与 jsp 站点的连接的正确方法是什么?

【问题讨论】:

  • HTML 和 IdHTTP1.ResponseCode 的值是多少?
  • HTML 的值是我要连接的 url 地址。未分配 IdHTTP1.ResposneCode 的值 - 程序应检查 ResponseCode 是否为 401 - 如果是,则程序应显示消息“登录名或密码错误”

标签: delphi indy indy10


【解决方案1】:

您不能仅依靠ResponseCode 来验证您的登录,尤其是在涉及基于 HTML 的登录表单时。是的,Post() 在返回 HTTP 错误代码时引发异常。所以Post() 没有引发异常的事实意味着服务器没有报告 HTTP 错误。但它发回的内容可能是 HTML 错误页面,甚至是显示失败消息的登录页面(这种情况并不少见)。所以当Post()“成功”时,你需要分析响应以确保它是你所期望的。

当我在网络浏览器中转到 https://e-skok.pl/eskok/login.jsp 并输入错误凭据时,我会被重定向回 https://e-skok.pl/eskok/login.jsp?err=1。当Post() 无异常退出时,您可以检查TIdHTTP.Response 以查看它是否是最后一个重定向到的URL。

顺便说一句,您调用的Post()TStrings 版本仅支持application/x-www-form-urlencoded 帖子,因此将Request.ContentType 设置为application/json 是错误的,因为您没有发布JSON 格式的数据。幸运的是,Post()ContentType 替换为正确的值。如果你真的想发布 JSON 数据,你必须使用 TStream 版本的 Post() 来代替。

更新:查看https://e-skok.pl/eskok/login.jsp的实际HTML后,我发现您最初显示的代码不正确。您没有正确解析登录 HTML(不存在 atlassian-token 字段),并且您使用错误的字段名称将凭据发布到错误的 URL。您必须改为发布到https://e-skok.pl/eskok/j2_security_check,它需要以下输入字段:

j_username
j_password
j_captcha_response

最后一个字段尤其需要额外的工作,因为它是动态生成的验证码。您必须解析 HTML 以提取验证码图像的 URL(https://e-skok.pl/eskok/captcha.jsp?d=1410970679796,其中 d 每次请求页面时都会更改),下载图像(您可以使用 TIdHTTP.Get())并将其显示在您应用的 UI,以便您可以在 j_captcha_response 字段中输入要发布的正确文本值。

尝试一下,然后报告你的结果。

【讨论】:

  • 那么,我应该为 TStream 更改 TStringList 吗?
  • 不,我只是指出您的代码中的一个错误。任何基于 HTML 的登录表单都不会使用 JSON 来携带表单字段值。只要服务器排除application/x-www-form-urlencoded 格式的数据(这是默认值,除非HTML <form> 标记指定另一种格式,通常是multipart/form-data),就可以使用TStringList
  • 那么,是否可以通过Indy组件连接jsp站点呢?还是我应该将其更改为另一种技术/组件?
  • 我也尝试在登录后从站点检查指定代码,但仍然无法正常工作。
  • @adam.cziker:当然有可能,我告诉过你怎么做。您只是还没有正确处理它。例如,当我运行您显示的代码时,authToken 没有获得正确的值,因为Pos('name="atlassian-token" value="', HTML) 返回 0。所以您在调用 Post() 之前没有正确解析登录 HTML,因此登录失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多