Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web & réseau Delphi Discussion :

Connexion à Gmail via Delphi 2010 avec composant Indy


Sujet :

Web & réseau Delphi

  1. #1
    Futur Membre du Club
    Connexion à Gmail via Delphi 2010 avec composant Indy
    Bonjour à tous,

    Je sais que ce sujet a déjà été abordé, mais malgré les échanges et différentes pistes sur le forum et le Net, j'ai toujours un problème pour me connecter à Gmail avec un composant TIdImap4.
    Pour faire simple, j'ai créé une application il y a un moment déjà (delphi 2010, composant Indy V10.5.5) qui se connecte à une boîte Gmail, récupère des messages (contenant des rapports de backups de base de données), décortique le contenu et envoie un mail si un backup n'a pas pu se faire correctement.
    Cette application a fonctionné très bien jusqu'à une certaine date. Puis un jour, sans aucun changement sur l'ordinateur, plus moyen de me connecter sur le compte Gmail, il se connecte puis se déconnecte avec le message "Connection closed gracefully"... not authenticated.

    J'ai pensé à une mise à jour de sécurité de Gmail. J'ai récupéré les dll à jour de openssl, j'ai revérifié le pare-feu et compagnie et j'ai re-trituré toutes les options de TIDImap et de TIdSSLIOHandlerSocketOpenSSL. Ça fait quelques combinaisons, mais aucune amélioration. Initialement je n'ai pas activé l'authentification en deux étapes dans Gmail, mais même en faisant et en créant un mot de passe d'application, rien à faire. Je commence à être à court d'idées. En faisant un pas à pas, je bloque a priori sur "GetResponse". Pour la gestion de connexion, je me suis inspirée initialement des codes que l'on trouve sur Internet, et ça marchait. Voici la procédure:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    procedure GetGmailMessages(const UserName, Password: string; Corpsdumail: TStrings);
    var
      S: string;
      MsgIndex: Integer;
      MsgObject: TIdMessage;
      PartIndex: Integer;
      Confirmes : array of integer;
      Supp, i : integer;
      Socks : TIdSocksInfo;
    begin
     
      //Création et paramétrage composant IMAP
      Corpsdumail.Clear;
      IMAPClient := TIdIMAP4.Create(nil);
     
      try
        OpenSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
     
        try
          //Paramétrage
          OpenSSLHandler.SSLOptions.Method := sslvSSLv3;
          OpenSSLHandler.SSLOptions.Mode := sslmUnassigned;//sslmClient ;//sslmUnassigned
          OpenSSLHandler.SSLOptions.VerifyMode := [];//[sslvrfClientOnce];
          OpenSSLHandler.SSLOptions.VerifyDepth := 0;
          IMAPClient.IOHandler := OpenSSLHandler;
          IMAPClient.Host := IMAPAddress;
          IMAPClient.UseTLS:=utuseExplicitTLS;
          IMAPClient.Port := IMAPPort;
          IMAPClient.Username := UserName;
          IMAPClient.Password := Password;
     
          Try
            IMAPClient.Connect;
            IMAPClient.Login;
          Except
             On e:exception do Showmessage(e.Message);
          End;
     
          try
            //Parcours boîte de réception
            if IMAPClient.SelectMailBox('INBOX') then
            begin
              Corpsdumail.BeginUpdate;
              FenPrincipale.MemEtat.Lines.Add('Parcours Boîte de réception');
              try
                for MsgIndex := 1 to IMAPClient.MailBox.TotalMsgs do
                begin
     
                  MsgObject := TIdMessage.Create(nil);
     
                  try
                    //Récup messages
                    S := '';
                    FenPrincipale.MemEtat.Lines.Add('Récupération du message');
                    IMAPClient.Retrieve(MsgIndex, MsgObject);
                    MsgObject.MessageParts.CountParts;
     
                    if MsgObject.MessageParts.TextPartCount > 0 then
                    begin
                      for PartIndex := 0 to MsgObject.MessageParts.Count - 1 do
                        if MsgObject.MessageParts[PartIndex] is TIdText then
                          S := S + TIdText(MsgObject.MessageParts[PartIndex]).Body.Text;
                          Corpsdumail.Add(S);
                    end
                    else
                      Corpsdumail.Add(MsgObject.Body.Text);
     
                    //Copie messages dans 'TRAITE' car IMAP ne connaît pas MOVE...
                    IMAPClient.CopyMsg(MsgIndex,'TRAITE');
                    FenPrincipale.MemEtat.Lines.Add('Classement comme ''TRAITE');
     
                  finally
                    //Libérations et fins de processus
                    MsgObject.Free;
                  end;
                end;  //endfor
     
                FenPrincipale.MemEtat.Lines.Add('Nettoyage Boîte de réception');
     
                //Une fois classés en Traités, on supprime les mails de Inbox
     
                //Vérification si le mail est non lu
                //FenPrincipale.IMAPClient.RetrieveFlags(MsgIndex,Flags);
                //if mfSeen in Flags  then
                Supp:=0;
                for i := 1 to IMAPClient.MailBox.TotalMsgs do
                begin
                  Setlength(Confirmes, Succ(Supp));
                  Confirmes[Supp] := i;
                  Inc(Supp);
                end;
                FenPrincipale.MemEtat.Lines.Add('Nettoyage Inbox');
                IMAPClient.DeleteMsgs(Confirmes);
                IMAPClient.ExpungeMailBox;
     
              finally
                Corpsdumail.EndUpdate;
              end;
            end;//endif
          finally
            IMAPClient.Disconnect;
          end;
        finally
          OpenSSLHandler.Free;
        end;
      finally
        IMAPClient.Free;
      end;
    end;



    Je suis preneuse de toute idée. Merci d'avance pour vos réponses.

  2. #2
    Rédacteur/Modérateur

    Bonjour,

    j'ai aussi des problèmes avec GMail mais c'est dû à la politique de sécurité de Google (application non autorisée) c'est peut être là le nœud du problème
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  3. #3
    Expert éminent sénior
    oui GMail a introduit des sécurités, il faut explicitement autoriser les connexions, en consultant le compte sur le site Gmail il doit y avoir un message en ce sens si je me souviens bien.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Futur Membre du Club
    Bonjour,

    Merci pour vos retours.

    Oui, j'ai regardé les options de sécurité du compte Google en question. J'ai activé l'accès moins sécurisé des applications, cela n'a pas suffi. Il n'y avait pas d'authentification en deux étapes initialement, mais pour autant cela ne marchait pas. Je l'ai activé et j'ai créé un mot de passe d'application, comme pour Outlook par exemple, mais ça ne marche pas mieux. Je ne sais pas ce que je pourrais encore alléger dans les options de sécurité.

    Le souci c'est que cette application que j'ai mis de côté pendant un long moment devient nécessaire pour notre entreprise, on a des dizaines de BDD à surveiller. Donc, je pense que je vais encore opter pour la solution de contournement. Je suis sûre qu'il existe des services de messagerie moins tatillons et pour ce que j'en ai à faire, cela sera suffisant.

    Je vous tiens au courant rapidement.

  5. #5
    Rédacteur/Modérateur

    À moins que ce soit le port ou la méthode d'identification (variables que l'on ne peut voir dans le code) qui ait changé (de manière plus ou moins unilatérale de la part de google coutumier du fait et n'envoyant qu'un courriel à peine explicatif
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  6. #6
    Futur Membre du Club
    Au niveau port, en imap j'utilise le 993 Comme préconisé par Google.
    Au niveau méthode d'identification vous pensez à quoi exactement? Ça je pourrais vérifier.

  7. #7
    Rédacteur/Modérateur

    En fait je pensais à ça
    Port pour SSL : 465 // en particulier ce port qui pourrait être explicite dans SSLIOHandler
    et tout ce qui pourrait avoir changé pour le SSL
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  8. #8
    Futur Membre du Club
    Ah d'accord.
    J'ai déjà essayé de préciser un port pour le SSLIOHandler, mais ce n'était pas le 465.
    Je vais tester.

  9. #9
    Futur Membre du Club
    Bonjour,

    Finalement j'ai fait table rase. J'ai fait d'abord une petite appli rien que pour tester la connexion à Gmail. J'ai mis à jour mes dll pour le ssl, mais en soi cela n'a pas résolu mon problème.
    J'ai surtout viré mes composants que j'avais sur ma fiche, j'ai tout créé à la volée avec très peu d'options paramétrés. Et là, ça marche à nouveau. Petit détail: j'ai créé un mot de passe d'application dans Gmail. Voici le code:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    procedure GetGmailMessages(const UserName, Password: string; Corpsdumail: TStrings);
    var
      S: string;
      MsgIndex: Integer;
      MsgObject: TIdMessage;
      PartIndex: Integer;
      Confirmes : array of integer;
      Supp, i : integer;
      Socks : TIdSocksInfo;
    begin
     
      //Création et paramétrage composant IMAP
      Corpsdumail.Clear;
      IMAPClient := TIdIMAP4.Create(nil);
     
      try
        OpenSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
     
        try
          //Paramétrage
          OpenSSLHandler.SSLOptions.Method := sslvSSLv23;
          IMAPClient.IOHandler :=OpenSSLHandler;
          IMAPClient.Host := 'imap.gmail.com';
          IMAPClient.UseTLS:=utuseImplicitTLS;
          //IMAPClient.Port := 993;
          IMAPClient.Username := UserName;
          IMAPClient.Password := Password;
          IMAPClient.Connect;
     
          try
            //Parcours boîte de réception
            if IMAPClient.SelectMailBox('INBOX') then
            begin
              Corpsdumail.BeginUpdate;
              FenPrincipale.MemEtat.Lines.Add('Parcours Boîte de réception');
              try
                for MsgIndex := 1 to IMAPClient.MailBox.TotalMsgs do
                begin
     
                  MsgObject := TIdMessage.Create(nil);
     
                  try
                    //Récup messages
                    S := '';
                    FenPrincipale.MemEtat.Lines.Add('Récupération du message');
                    IMAPClient.Retrieve(MsgIndex, MsgObject);
                    MsgObject.MessageParts.CountParts;
     
                    if MsgObject.MessageParts.TextPartCount > 0 then
                    begin
                      for PartIndex := 0 to MsgObject.MessageParts.Count - 1 do
                        if MsgObject.MessageParts[PartIndex] is TIdText then
                          S := S + TIdText(MsgObject.MessageParts[PartIndex]).Body.Text;
                          Corpsdumail.Add(S);
                    end
                    else
                      Corpsdumail.Add(MsgObject.Body.Text);
     
                    //Copie messages dans 'TRAITE' car IMAP ne connaît pas MOVE...
                    IMAPClient.CopyMsg(MsgIndex,'TRAITE');
                    FenPrincipale.MemEtat.Lines.Add('Classement comme ''TRAITE');
     
                  finally
                    //Libérations et fins de processus
                    MsgObject.Free;
                  end;
                end;  //endfor
     
                FenPrincipale.MemEtat.Lines.Add('Nettoyage Boîte de réception');
     
                //Une fois classés en Traités, on supprime les mails de Inbox
     
                //Vérification si le mail est non lu
                //FenPrincipale.IMAPClient.RetrieveFlags(MsgIndex,Flags);
                //if mfSeen in Flags  then
                Supp:=0;
                for i := 1 to IMAPClient.MailBox.TotalMsgs do
                begin
                  Setlength(Confirmes, Succ(Supp));
                  Confirmes[Supp] := i;
                  Inc(Supp);
                end;
                FenPrincipale.MemEtat.Lines.Add('Nettoyage Inbox');
                IMAPClient.DeleteMsgs(Confirmes);
                IMAPClient.ExpungeMailBox;
     
              finally
                Corpsdumail.EndUpdate;
              end;
            end;//endif
          finally
            IMAPClient.Disconnect;
          end;
        finally
          OpenSSLHandler.Free;
        end;
      finally
        IMAPClient.Free;
      end;
    end;


    Youpie! Je considère le sujet comme résolu.