通过gmail api

时间:2016-06-21 15:00:50

标签: c# oauth-2.0 gmail-api gmail-imap

我有一个测试平台应用程序,它不断运行以下载Gmail帐户收件箱中的邮件数量。我通过gmail-api连接请求登录令牌并登录该帐户。我面临的问题是,在每次迭代时,访问令牌的到期时间是3600s,即它永远不会改变。我是否需要每次都重新下载访问令牌以查看它是否需要刷新,或者api是否为我处理了这个?

ImapClientAE.Net库的一部分。

见下面的代码:

try
{
    X509Certificate2 certificate = new X509Certificate2("certificate.p12", "notasecret", X509KeyStorageFlags.Exportable);
    ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential
        .Initializer("Service account address")
    {
        //Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
        Scopes = new[] { "https://mail.google.com/" },
        User = "email address"
    }.FromCertificate(certificate));

    Task<bool> result = credential.RequestAccessTokenAsync(CancellationToken.None);
    if (!result.Result)
    {
        Console.WriteLine("Failed to connect to gmail!");
    }

    using (ImapClient imap = new ImapClient())
    {
        imap.AuthMethod = ImapClient.AuthMethods.SaslOAuth;

        imap.Connect("imap.gmail.com", 993, true, false);
        if (!imap.IsConnected)
        {
            throw new Exception("Unable to connect to the host");
        }

        imap.Login("email address", credential.Token.AccessToken);
        if (!imap.IsAuthenticated)
        {
            throw new Exception("Currently not authenticated (2)?");
        }

        string sourceMailBox = "Inbox";
        imap.SelectMailbox(sourceMailBox);

        while (true)
        {
            int messageCount = imap.GetMessageCount(sourceMailBox);

            Console.WriteLine("Messages in '" + sourceMailBox + "': " + messageCount);
            Console.WriteLine("Token expires in {0}s", credential.Token.ExpiresInSeconds);

            System.Threading.Thread.Sleep(10000);
        }
    }
}
catch(Exception ex)
{
    Console.Error.WriteLine("IMAP Exception: " + ex.Message);
    Console.Error.WriteLine(ex.ToString());
}

示例输出(注意我没有写出GetResponse行):

  

GetResponse():&#39; *状态&#34;收件箱&#34; (MESSAGES 1)&#39;

     

GetResponse():&#39; xm070 OK Success&#39;

     

&#39;收件箱中的邮件&#39;:1

     

令牌在3600s到期

     

GetResponse():&#39; *状态&#34;收件箱&#34; (MESSAGES 1)&#39;

     

GetResponse():&#39; xm071确定成功&#39;

     

&#39;收件箱中的邮件&#39;:1

     

令牌在3600s到期

运行约3100秒后,它给了我以下异常,我认为这是因为令牌过期。

  

IMAP异常:无法将数据写入传输连接:已建立的连接已被主机中的软件中止。

     

System.IO.IOException:无法将数据写入传输连接:已建立的连接已被主机中的软件中止。 ---&GT; System.Net.Sockets.SocketException:已建立的连接已被主机中的软件中止

     

at System.Net.Sockets.Socket.Send(Byte [] buffer,Int32 offset,Int32 size,SocketFlags socketFlags)

     

在System.Net.Sockets.NetworkStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)

     

---内部异常堆栈跟踪结束---

     

在System.Net.Sockets.NetworkStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)

     

at System.Net.Security._SslStream.StartWriting(Byte [] buffer,Int32 offset,Int32 count,AsyncProtocolRequest asyncRequest)

     

at System.Net.Security._SslStream.ProcessWrite(Byte [] buffer,Int32 offset,Int32 count,AsyncProtocolRequest asyncRequest)

     

at System.Net.Security.SslStream.Write(Byte [] buffer,Int32 offset,Int32 count)

     

在AE.Net.Mail.TextClient.SendCommand(字符串命令)

     

在AE.Net.Mail.ImapClient.OnLogout()

     

在AE.Net.Mail.TextClient.Logout()

     

在AE.Net.Mail.TextClient.Disconnect()

     

在AE.Net.Mail.TextClient.Dispose(布尔处理)

     

在AE.Net.Mail.ImapClient.Dispose(布尔处理)

     

在AE.Net.Mail.TextClient.Dispose()

     

中的

中的GmailOAuth.Program.DoWork()      

c:\ Projects \ Development \ EmailSystem \ GmailOAuth \ GmailOAuth \ Program.cs:第82行

1 个答案:

答案 0 :(得分:1)

Documentation Token.ExpiresInSeconds中所述,可以为您提供令牌的到期时间,并且其值不会自动更新。如果您想知道刷新令牌的剩余时间,您必须找到令牌发出时间(Token.Issued)与当前时间(Datetime.Now)之间的差异,并检查它是否小于令牌的到期时间

//calculate time to expire by finding difference between current time and time when token is issued

if((DateTime.Now-credential.Token.Issued).TotalSeconds>credential.Token.ExpiresInSeconds) 
{
    //refresh your token
} 
else 
{
    //your method call
}

您还可以使用Token.IsExpired()方法检查令牌是否已过期。

if (credential.Token.IsExpired(credential.Flow.Clock))
{
    //refresh your token
} 
else 
{
    //your method call
}
相关问题