Jac*_*k U 1 delphi gmail indy10 delphi-xe2
我的问题是:为什么 gmail 给我这个错误:
不接受用户名和密码。如需了解详情,请 访问 http://support.google.com/mail/bin/answer.py?answer=14257 lp8sm18275694wic.17 - gsmtp
我尝试了一切,一大堆选项:SSL、TSL、SASL,但仍然没有。在某处我发现谷歌需要一些 OAUTH2 SASL 方法,这些方法将在 Indy 中完成。
当然,在 Delphi 6 和 Indy 9 上,使用 ssl 在端口 465 上使用适当的 eay dll 工作正常。任何人都知道该怎么做?
当然我安装了http://slproweb.com/products/Win32OpenSSL.html我有人问过......
这是代码:
procedure send(Recipientemail, AccountName, Pass, EmailSMTP,EmailPortNo :string);
var
lTextPart: TIdText;
lImagePart: TIdAttachmentfile;
IdSMTP1: TIdSMTP;
IdMsg: TIdMessage;
SSLHandler:TIdSSLIOHandlerSocketOpenSSL;
IdUserPassProv1: TIdUserPassProvider;
IdSASLLogin1: TIdSASLLogin;
IdSASLCRAMMD5: TIdSASLCRAMMD5;
IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
IdSASLPlain: TIdSASLPlain;
IdSASLLogin: TIdSASLLogin;
IdSASLSKey: TIdSASLSKey;
IdSASLOTP: TIdSASLOTP;
IdSASLAnonymous: TIdSASLAnonymous;
IdSASLExternal: TIdSASLExternal;
begin
IdSMTP1:=TIdSMTP.Create(nil);
IdMsg:=TIdMessage.Create(nil);
IdSMTP1.Host:=EmailSMTP;
IdSMTP1.Port:=EmailPortNo;
//IdSMTP1.Username:=trim(AccountName);//tried with or without
//IdSMTP1.Password:=trim(Pass);//tried with or without
TIdSSLContext.Create.Free;
SSLHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP1);
SSLHandler.SSLOptions.Method := sslvSSLv3;
SSLHandler.SSLOptions.Mode := sslmClient;
IdSMTP1.IOHandler := SSLHandler;
if (IdSMTP1.port = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSASLLogin1:=TIdSASLLogin.Create(IdSMTP1);
IdUserPassProv1:=TIdUserPassProvider.Create(IdSMTP1);
IdUserPassProv1.Password:=trim(EmailHasloKonta);
IdUserPassProv1.Username:=trim(EmailNazwaKonta);
IdSMTP1.AuthType:=satSASL;
IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(idSMTP1);
IdSASLCRAMSHA1.UserPassProvider := IdUserPassProv1;
IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(idSMTP1);
IdSASLCRAMMD5.UserPassProvider := IdUserPassProv1;
IdSASLSKey := TIdSASLSKey.Create(idSMTP1);
IdSASLSKey.UserPassProvider := IdUserPassProv1;
IdSASLOTP := TIdSASLOTP.Create(idSMTP1);
IdSASLOTP.UserPassProvider := IdUserPassProv1;
IdSASLAnonymous := TIdSASLAnonymous.Create(idSMTP1);
IdSASLExternal := TIdSASLExternal.Create(idSMTP1);
IdSASLLogin := TIdSASLLogin.Create(idSMTP1);
IdSASLLogin1.UserPassProvider:=IdUserPassProv1;
IdSASLPlain := TIdSASLPlain.Create(idSMTP1);
IdSASLPlain.UserPassProvider := IdUserPassProv1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLSKey;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLOTP;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLAnonymous;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLExternal;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLLogin1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLPlain;
IdMsg.CharSet:=CmbEncod.Text;
IdMsg.From.Address:=EmailAdresNadawcy;
IdMsg.From.Name:=ToISO_8859_2(true, EmailNadawca);
IdMsg.Recipients.Add.Address:=email;
if EmailDoWiad<>'' then IdMsg.BccList.Add.Address:=EmailDoWiad;
IdMsg.ContentType:='multipart/relative';//; charset='+CmbEncod.Text;
IdMsg.Subject:=ifthen(TytulEmaila='',translate('Potwierdzenie rezerwacji'),TytulEmaila);
IdMsg.Body.Clear;
IdMsg.Body.Text:='';
lTextPart := TIdText.Create(IdMsg.MessageParts);
lTextPart.Body.text:='Some body text';
lTextPart.ContentType := 'text/plain';
try
IdSMTP1.Connect;
//IdSMTP1.Authenticate; //tried with or without
try
try
IdSMTP1.Send(IdMsg);
except
on e: exception do
MessageDlg('Sending error:'#13+
e.message,
mtinformation,[mbok],0);
end;
finally
IdSMTP1.Disconnect;
end;
finally
IdSMTP1.Disconnect;
IdUserPassProv1.free;
IdSASLLogin1.free;
IdSASLCRAMMD5.free;
IdSASLCRAMSHA1.free;
IdSASLPlain.free;
IdSASLLogin.free;
IdSASLSKey.free;
IdSASLOTP.free;
IdSASLAnonymous.free;
IdSASLExternal.free;
lTextPart.Free;
lImagePart.Free;
SSLHandler.free;
IdSMTP1.Free;
IdMsg.Free;
SSLHandler.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
使用最新的 Indy 版本 (10.6.1),我可以TIdSMTP使用 Indy 的 SASL 组件以及 SSL(UseTLS=utUseImplicitTLS在端口 465 上)和 TLS(UseTLS=utUseExplicitTLS在端口 587 上)成功连接 Gmail 并进行身份验证,使用与您所显示的类似的代码。尽管普遍认为,OAUTH2还不是必需的。
事实上,您收到人类可读的身份验证错误意味着 SSL/TLS 部分工作正常,因此这严格来说是 SASL 问题。
如果您的 Gmail 帐户使用两步验证,请确保您已在 Gmail 帐户设置中创建应用程序密码,则无法使用 Gmail 主密码。阅读 Gmail 的文档了解更多详细信息:
话虽如此,我建议您对所显示的代码进行的唯一更改是:
设置UseTLS属性可能会改变Port属性值,所以应该UseTLS先设置,然后再设置Port为所需的值:
if (EmailPortNo = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSMTP1.Port := EmailPortNo;
Run Code Online (Sandbox Code Playgroud)你不需要创建和销毁一个TIdSSLContext对象,所以摆脱它。手动创建的唯一原因TIdSSLContext是它可以调用该IdSSLOpenSSL.LoadOpenSSLLibrary()函数,该函数是公共的,因此您可以在需要时直接调用它(在这种情况下您实际上并不需要)。
multipart/relative不是有效的 ContentType。你的意思是multipart/related相反吗?您的TIdMessage不包含多个部分,因此您不应该一multipart开始就使用 ContentType。
大多数调用Free()都是多余的,因为您将 指定TIdSMTP为除 之外的所有内容的所有者TIdMessage。您无需手动释放 SASL 组件,您可以让其TIdSMTP为您执行此操作。
你打了IdSMTP1.Disconnect()两次电话。你不需要那个。
| 归档时间: |
|
| 查看次数: |
2050 次 |
| 最近记录: |