IMAP4 无法在 Delphi 2010 中使用 Gmail 进行身份验证

问题描述 投票:0回答:1

我对 Indy 很陌生,所以如果这里有一些明显的问题,我深表歉意。

我正在尝试从 Gmail 收件箱中检索电子邮件,然后将它们保存到一组

TIdMessage
对象中。

我找不到任何详细说明如何设置它的文档,也找不到工作示例(Indy 文档已损坏),而且我处理电子邮件的知识基本上为零。

procedure TfrmEmail.LoadInbox;
var
  IMAP:TIdIMAP4;
  iLength,i:integer;
  SSL:TIdSSLIOHandlerSocketOpenSSL;
begin
  SSL:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  //Set-Up SSL
  with SSL.SSLOptions do
  begin
    Method:=sslvTLSv1;
    Mode:=sslmClient;
    VerifyMode:=[];
    VerifyDepth:=0;
  end;

  IMAP:=TIdIMAP4.Create(Nil);
  //IMAP settings
  with IMAP do
  begin
    IOHandler:=SSL;
    Host:='imap.gmail.com';
    Port:=993;
    Username:={[email protected]};
    Password:={app password};
    UseTLS:=utUseImplicitTLS;
    Connect; //works up until here
    SelectMailBox('INBOX');//error here
  end;

  iLength:=IMAP.RetrieveMailBoxSize;
  ShowMessage(inttostr(iLength));
  SetLength(ArrInboxMessages,iLength);
  for i := 1 to iLength do
  begin
    IMAP.Retrieve(i,ArrInboxMessages[i]);
  end;
  IMAP.Disconnect;
  IMAP.Free;
end;

我的代码在

Connect
部分之前一直有效,但是一旦我尝试选择收件箱,我就会收到异常:
EIdConnectionStateError

我的连接状态未经身份验证,我认为这是因为我没有使用 SASL 身份验证。

另一个问题可能是我使用的是 TLSv1,但这适用于 SMTP,并且我无法在 Delphi 2010 上更新到最新版本。

如果有人能够识别问题并提供一个可行的示例/在哪里可以找到示例,那将非常有帮助。

delphi imap indy delphi-2010 gmail-imap
1个回答
0
投票

使用应用程序密码并将

TIdIMAP4.AuthType
设置为
iatUserPass
(其默认设置)应该可以正常工作,您不需要使用 SASL+OAuth(尽管 GMail 更喜欢这样做)。

您显示的代码对我来说看起来不错。

TIdIMAP4.Connect()
有一个可选的
AAutoLogin
参数,默认为
True
,因此
TIdIMAP4.Login()
应该在
Connect()
退出之前被调用。如果
Login()
失败,您将收到不同的异常,并且您将无法首先到达
TIdIMAP4.SelectMailBox()

话虽如此,您收到的

EIdConnectionStateError
异常意味着当您调用
TIdIMAP4.ConnectionState
时,
csAuthenticated
不是
csSelected
(或
SelectMailBox()
)。
ConnectionState
csNonAuthenticated
Connect()
的最开始设置为
Login()
,然后如果身份验证成功,
Login()
将其更新为
csAuthenticated
。 因此,除非
Login()
被绕过,否则您的错误应该是不可能的,即如果
AAutoLogin=False

如果需要,您可以尝试在

Login()
之后和
Connect()
之前显式调用
SelectMailBox()
,例如:

Connect;
if ConnectionState <> csAuthenticated then
  Login;
SelectMailBox('INBOX');

更新

我没有注意到你使用的是非常旧版本的 Delphi。

我仔细检查了

TIdIMAP4
的源代码,了解 Delphi 2010 附带的 Indy 版本,我发现
Login()
当时实际上并没有在失败时引发异常。该问题在一年后得到解决(可能在 Delphi XE2 中发布)。

因此,在您的情况下,身份验证可能实际上失败,并且当

ConnectionState
/
csNonAuthenticated
无一例外退出时,
Connect()
被保留为
Login()
。这可以解释你的情况。

因此,您需要仔细检查您的凭据是否正确。您还可以在

TIdIMAP4.LastCmdResult.Code
/
'OK'
退出后检查
Connect()
是否为
Login()
,例如:

Connect;
if LastCmdResult.Code <> 'OK' then
  RaiseExceptionForLastCmdResult;
SelectMailBox('INBOX');

但是,我建议从其 GitHub 存储库升级到 Indy 的最新版本,以确保您拥有所有最新的修复程序,包括

Login()
在失败时引发异常的修复程序。即使您使用的是旧的 Delphi 版本,您也可以更新 Indy,因为 Indy 仍然支持 Delphi 2010。请参阅存储库 Wiki 中的更新 Indy 文档。

© www.soinside.com 2019 - 2024. All rights reserved.