.NET Gmail OAuth2 для нескольких пользователей

Мы создаем решение, которое будет необходимо для доступа наших клиентов к учетным записям Gmail для чтения / отправки почты. При регистрации аккаунта у нас будет всплывающее окно, чтобы клиент мог выполнить страницу аутентификации Gmail, а затем бэкэнд-процесс, чтобы периодически читать их электронные письма.

Документация, кажется, не покрывает этот вариант использования. Например, https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth говорит, что клиентские токены должны храниться в client_secrets.json - что если у нас тысячи клиентов, что тогда?

Сервисные учетные записи предназначены для информации не пользователя, а скорее для данных приложения. Кроме того, если я использую GoogleWebAuthorizationBroker и пользователь удалил доступ или срок действия маркеров истек, я не хочу, чтобы приложение моего сервера внутреннего интерфейса открывало веб-браузер, как это, похоже, происходит.

Я мог бы предположить, что мог бы использовать IMAP/SMTP для достижения этой цели, но я не думаю, что было бы хорошей идеей хранить эти учетные данные в моей базе данных, и при этом я не думаю, что Google также хочет этого.

Есть ли ссылка на то, как это можно сделать?

2 ответа

Решение

Хотя ответ @ Hurcane, скорее всего, правильный (не пробовал), это то, что я получил за последние несколько дней. Я действительно не хотел де-сериализовать данные из файла, чтобы это работало, поэтому я как-то разобрал это решение

  1. Веб-приложение, чтобы получить одобрение клиента
    • Использование AuthorizationCodeMvcApp от Google.Apis.Auth.OAuth2.Mvc и документации
  2. Сохранение полученного доступа и обновление токенов в БД
  3. Используйте AE.Net.Mail для первоначального доступа IMAP с токеном доступа.
  4. Backend также использует AE.Net.Mail для доступа
    • Если срок действия токена истек, используйте токен обновления для получения нового токена доступа.

Я не сделал отправляющую часть, но я предполагаю, что SMTP будет работать аналогично.

Код основан на сообщениях SO и блога:

t = EF-объект, содержащий информацию о токене

ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);

Чтобы получить обновленный токен доступа (требуется обработка ошибок) (используется тот же API, что и в шаге 1 выше)

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;
            }

У меня такая же ситуация. Мы планируем функцию, при которой пользователь одобряет доступ к отправке электронной почты от своего имени, но фактическая отправка сообщений выполняется неинтерактивным процессом (запланированная задача, выполняемая на сервере приложений).

Я думаю, что окончательный ответ - настроенный IAuthorizationCodeFlow, который поддерживает доступ только с существующим токеном и не выполняет процесс авторизации. Я, вероятно, хотел бы, чтобы поток имитировал ответ, который происходит, когда пользователь нажимает кнопку "Запретить" в интерактивном потоке. То есть любая необходимость получить токен авторизации просто вернет "отклоненный" AuthorizationResult.

Мой проект все еще находится в фазе исследований и разработок, и я даже пока не делаю проверки концепции. Я предлагаю этот ответ в надежде, что он поможет кому-то еще разработать конкретное решение.

Другие вопросы по тегам