我们正在构建一个解决方案,需要访问我们的客户Gmail帐户才能阅读/发送邮件。在帐户注册时,我们会为客户弹出一个Gmail身份验证页面,然后是后端流程,以便定期阅读他们的电子邮件。
文档似乎并不涵盖此用例。例如https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth表示客户端令牌应该存储在client_secrets.json中 - 如果我们有1000个客户端,那么呢?
服务帐户用于非用户信息,而是用于应用程序数据。此外,如果我使用 GoogleWebAuthorizationBroker 并且用户已删除访问权限或令牌已过期,我也不希望我的后端服务器应用程序弹出一个网络浏览器,因为这似乎可以。
我想我可以使用IMAP / SMTP来实现这一点,但我不认为将这些凭据存储在我的数据库中是个好主意,我也不认为Google也想要这样做。
是否有关于如何实现这一目标的参考?
答案 0 :(得分:1)
我有同样的情况。我们正在计划用户批准访问权限以代表他们发送电子邮件的功能,但实际发送的消息由非交互式进程执行(在应用程序服务器上运行的计划任务)。
我认为最终的答案是定制的IAuthorizationCodeFlow,它只支持使用现有令牌进行访问,并且不会执行授权过程。我可能会让流模拟用户单击交互式流上的拒绝按钮时发生的响应。也就是说,获得授权令牌的任何需要都只会返回“拒绝”的AuthorizationResult。
我的项目仍在R& D阶段,我甚至还没有进行概念验证。我提供这个答案,希望能帮助其他人制定具体的解决方案。
答案 1 :(得分:0)
虽然@ hurcane的回答很可能是正确的(没有试过),这就是我过去几天的工作。我真的不想从文件中取消/序列化数据以使其工作,所以我有点捣乱了这个解决方案
我没有完成发送部分,但我认为SMTP的工作方式类似。
该代码基于SO&博客文章:
t =包含令牌信息的EF对象
ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);
获取更新的Access令牌(需要错误处理)(使用与上面步骤#1相同的API)
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["refresh_token"] = refresh;
data["client_id"] = "(Web app OAuth id)";
data["client_secret"] = "(Web app OAuth secret)";
data["grant_type"] = "refresh_token";
var response = wb.UploadValues(@"https://accounts.google.com/o/oauth2/token", "POST", data);
string Tokens = System.Text.Encoding.UTF8.GetString(response);
var token = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Tokens);
at = token.access_token;
return at;
}