我在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站点的连接的正确方法是什么?
答案 0 :(得分:3)
您无法单独依靠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
以查看这是否是重定向到的最后一个网址。
顺便说一句,您呼叫的TStrings
版Post()
仅支持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以提取验证码图像的网址{https://e-skok.pl/eskok/captcha.jsp?d=1410970679796
,每次请求页面时d
都会更改),下载图像(您可以使用TIdHTTP.Get()
那个)并将其显示在你应用的用户界面中,这样你就可以输入正确的文本值,在j_captcha_response
字段中发布。
试试,然后用结果报告。