.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, скорее всего, правильный (не пробовал), это то, что я получил за последние несколько дней. Я действительно не хотел де-сериализовать данные из файла, чтобы это работало, поэтому я как-то разобрал это решение
- Веб-приложение, чтобы получить одобрение клиента
- Использование AuthorizationCodeMvcApp от Google.Apis.Auth.OAuth2.Mvc и документации
- Сохранение полученного доступа и обновление токенов в БД
- Используйте AE.Net.Mail для первоначального доступа IMAP с токеном доступа.
- 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.
Мой проект все еще находится в фазе исследований и разработок, и я даже пока не делаю проверки концепции. Я предлагаю этот ответ в надежде, что он поможет кому-то еще разработать конкретное решение.