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