适用于多个用户的 .NET Gmail OAuth2
.NET Gmail OAuth2 for multiple users
我们正在构建一个解决方案,需要访问我们的客户 Gmail 帐户以 read/send 邮件。在帐户注册时,我们会有一个弹出窗口供我们的客户执行 Gmail 身份验证页面,然后是一个后端进程来定期阅读他们的电子邮件。
文档似乎没有涵盖这个用例。例如 https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth 表示客户端令牌应存储在 client_secrets.json 中 - 如果我们有 1000 个客户端怎么办?
服务帐户用于非用户信息,而是应用程序数据。此外,如果我使用 GoogleWebAuthorizationBroker 并且用户已删除访问权限或令牌已过期,我不希望我的后端服务器应用程序弹出网络浏览器,就像这看起来一样。
我想我可以使用 IMAP/SMTP 完成此操作,但我认为将这些凭据存储在我的数据库中不是一个好主意,我认为 Google 也不希望这样做。
是否有关于如何实现这一点的参考?
我也有这种情况。我们正在计划一项功能,用户批准访问权限以代表他们发送电子邮件,但实际发送消息是由 non-interactive 进程(应用程序服务器上的计划任务 运行)执行的。
我认为最终的答案是定制的IAuthorizationCodeFlow,它只支持使用现有令牌访问,并且不会执行授权过程。我可能会让流程模拟用户在交互式流程中单击“拒绝”按钮时发生的响应。也就是说,任何获得授权令牌的需求都将简单地 return 一个 "denied" AuthorizationResult.
我的项目还处于研发阶段,我什至还没有进行概念验证。我提供这个答案是希望它能帮助其他人制定具体的解决方案。
虽然@hurcane 的回答很可能是正确的(还没有尝试过),但这就是我过去几天的工作。我真的不想 de/serialize 文件中的数据才能正常工作,所以我有点混搭了这个解决方案
- 获得客户认可的网络应用程序
- 使用 Google.Apis.Auth.OAuth2.Mvc 和文档
中的 AuthorizationCodeMvcApp
- 在数据库中存储生成的访问和刷新令牌
- 使用 AE.Net.Mail 使用访问令牌进行初始 IMAP 访问
- 后端也使用AE.Net.Mail访问
- 如果令牌已过期,则使用刷新令牌获取新的访问令牌。
我还没有完成发送部分,但我想 SMTP 的工作方式类似。
代码基于 SO 和博文:
t = 包含令牌信息的 EF 对象
ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);
获取更新的访问令牌(需要错误处理)(使用与上述步骤 #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;
}
我们正在构建一个解决方案,需要访问我们的客户 Gmail 帐户以 read/send 邮件。在帐户注册时,我们会有一个弹出窗口供我们的客户执行 Gmail 身份验证页面,然后是一个后端进程来定期阅读他们的电子邮件。
文档似乎没有涵盖这个用例。例如 https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth 表示客户端令牌应存储在 client_secrets.json 中 - 如果我们有 1000 个客户端怎么办?
服务帐户用于非用户信息,而是应用程序数据。此外,如果我使用 GoogleWebAuthorizationBroker 并且用户已删除访问权限或令牌已过期,我不希望我的后端服务器应用程序弹出网络浏览器,就像这看起来一样。
我想我可以使用 IMAP/SMTP 完成此操作,但我认为将这些凭据存储在我的数据库中不是一个好主意,我认为 Google 也不希望这样做。
是否有关于如何实现这一点的参考?
我也有这种情况。我们正在计划一项功能,用户批准访问权限以代表他们发送电子邮件,但实际发送消息是由 non-interactive 进程(应用程序服务器上的计划任务 运行)执行的。
我认为最终的答案是定制的IAuthorizationCodeFlow,它只支持使用现有令牌访问,并且不会执行授权过程。我可能会让流程模拟用户在交互式流程中单击“拒绝”按钮时发生的响应。也就是说,任何获得授权令牌的需求都将简单地 return 一个 "denied" AuthorizationResult.
我的项目还处于研发阶段,我什至还没有进行概念验证。我提供这个答案是希望它能帮助其他人制定具体的解决方案。
虽然@hurcane 的回答很可能是正确的(还没有尝试过),但这就是我过去几天的工作。我真的不想 de/serialize 文件中的数据才能正常工作,所以我有点混搭了这个解决方案
- 获得客户认可的网络应用程序
- 使用 Google.Apis.Auth.OAuth2.Mvc 和文档 中的 AuthorizationCodeMvcApp
- 在数据库中存储生成的访问和刷新令牌
- 使用 AE.Net.Mail 使用访问令牌进行初始 IMAP 访问
- 后端也使用AE.Net.Mail访问
- 如果令牌已过期,则使用刷新令牌获取新的访问令牌。
我还没有完成发送部分,但我想 SMTP 的工作方式类似。
代码基于 SO 和博文:
t = 包含令牌信息的 EF 对象
ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);
获取更新的访问令牌(需要错误处理)(使用与上述步骤 #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;
}