我们如何使用 Mailkit 在 ASP.NET 核心网站中存储用户的 GMail OAuth 访问令牌?

How do we store a user's GMail OAuth access token with Mailkit in an ASP.NET Core web site?

我正在尝试使用 Mailkit 和 OAuth 来读取用户的 Gmail 收件箱,并遵循 Mailkit FAQ 中的示例代码。作为记录,这是我正在使用的代码...

请注意,我目前将令牌存储在网站内容根目录中的一个文件中,直到我开始工作。之后,我将实现一个 Entity Framework IDataStore,所以请不要担心这里显示的代码的安全问题

private async Task<ImapClient> GetMailClientOAuth(string account, string clientId, string clientSecret) {
  ClientSecrets clientSecrets = new() {
    ClientId = clientId,
    ClientSecret = clientSecret
  };
  GoogleAuthorizationCodeFlow codeFlow = new(new GoogleAuthorizationCodeFlow.Initializer {
    DataStore = new FileDataStore($@"{_env.ContentRootPath}\{account}"),
    Scopes = new[] { "https://mail.google.com/" },
    ClientSecrets = clientSecrets
  });

  LocalServerCodeReceiver codeReceiver = new();
  AuthorizationCodeInstalledApp authCode = new(codeFlow, codeReceiver);
  UserCredential credential = await authCode.AuthorizeAsync(account, CancellationToken.None);

  if (authCode.ShouldRequestAuthorizationCode(credential.Token)) {
    await credential.RefreshTokenAsync(CancellationToken.None);
  }

  SaslMechanismOAuth2 oauth2 = new(credential.UserId, credential.Token.AccessToken);

  ImapClient client = new();
  await client.ConnectAsync("imap.gmail.com", 993, SecureSocketOptions.SslOnConnect);
  await client.AuthenticateAsync(oauth2);
  return client;
}

代码在测试控制台应用程序中运行良好,我现在正在尝试将代码集成到我的 ASP.NET 核心网络应用程序中。

我在我的 Google 云仪表板中设置了一个网络项目,添加了 Gmail API 并创建了一个 OAuth 凭证,就像我为控制台应用程序所做的那样。

当我尝试访问 Gmail 的代码时,window 在我的浏览器中弹出一条消息...

Authorization Error

Error 400: redirect_uri_mismatch

The redirect URI in the request, http://localhost:54392/authorize/, does not match the ones authorized for the OAuth client

现在我不知道它是从哪里获取 http://localhost:54392/authorize/ 的,因为它与我正在使用的任何东西都没有任何相似之处(不是我给它的任何东西 URL 无论如何),但我遵循了消息中的 link,并在我的网站上设置了一个 URL(当我的本地机器上 运行 时)。

我已经仔细检查过此 URL 是否已与凭据一起保存,但是当我尝试访问我网站上的页面时,我遇到了同样的错误,同样的 URL它认为应该在那里。

我已经检查了客户端 ID 和密码,我肯定使用的是正确的。

有人知道它从哪里获取 http://localhost:54392/authorize/ 吗?我如何告诉它使用其他东西?

谢谢

不确定这样做是否正确,但我通过将项目类型设置为不需要重定向 URI 的桌面应用程序解决了这个问题。