Google Calendar API возвращает invalid_grant и неверный запрос - PullRequest
5 голосов
/ 09 мая 2020

В моей среде разработки у меня есть пользователь, которому я только что получил токен OAuth для следующих областей.

Все выглядит нормально, и я сохраняю токен для пользователя. Затем я запрашиваю список календарей для пользователя и получаю invalid_grant с неверным запросом. Я пробую тот же запрос с токеном другого пользователя (тоже в моей среде разработки), и он работает правильно.

Изначально у меня была только первая настройка области, то есть доступ на уровне записи. Это то, с чем были созданы все существующие токены. Во время тестирования я добавил другие области.

Я попытался обновить пакеты NuGet для API Google в своем проекте.

Это мой класс, который выполняет вызовы.

public class GoogleCalendarAdapter : ICalendarAdapter {
    #region attributes
    private readonly ISiteAuthTokenQueryRepository _tokenRepo;
    private readonly GoogleCalendarSettings        _settings;

    private const string APPNAME = "REDACTED";

    private const string ACL_OWNER = "owner";
    private const string ACL_WRITER = "writer";
    #endregion

    #region ctor
    public GoogleCalendarAdapter(ISiteAuthTokenQueryRepository tokenRepo,
                                 GoogleCalendarSettings        settings) {
        _tokenRepo = tokenRepo;
        _settings  = settings;
    }
    #endregion

    #region methods
    private GoogleAuthorizationCodeFlow BuildAuthorizationCodeFlow() {
        return new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer() {
            ClientSecrets = BuildClientSecrets(),
            Scopes        = BuildScopeList()
        });
    }

    private CalendarService BuildCalendarService(SiteAuthToken token) {

        return new CalendarService(new BaseClientService.Initializer() {
                ApplicationName       = APPNAME,
                HttpClientInitializer = BuildUserCredential(token)
        });
    }

    private ClientSecrets BuildClientSecrets() {
        return new ClientSecrets() {
            ClientId = _settings.ClientId,
            ClientSecret = _settings.ClientSecret
        };
    }

    private string[] BuildScopeList() {
        return new [] { CalendarService.Scope.Calendar };
    }

    private UserCredential BuildUserCredential(SiteAuthToken token) {
        TokenResponse responseToken = new TokenResponse() {
            AccessToken  = token.AccessToken,
            RefreshToken = token.RefreshToken
        };

        return new UserCredential(BuildAuthorizationCodeFlow(), APPNAME, responseToken);
    }

    public async Task<List<Cal>> GetAllWritableCalendars(Guid siteGuid) {
        SiteAuthToken token = await GetToken(siteGuid);
        CalendarService svc = BuildCalendarService(token);

        IList<CalendarListEntry> calendars = svc.CalendarList
                                                .List()
                                                .Execute()
                                                .Items;

        return calendars.Where(c => c.AccessRole.Equals(ACL_OWNER,  StringComparison.CurrentCultureIgnoreCase) ||
                                    c.AccessRole.Equals(ACL_WRITER, StringComparison.CurrentCultureIgnoreCase))
                        .Select(c => new Cal() {
                            Id   = c.Id,
                            Name = c.Summary
                        })
                        .OrderBy(o => o.Name)
                        .ToList();
    }

    public async Task<Cal> GetCalendar(Guid siteGuid, string calendarId) {
        SiteAuthToken token = await GetToken(siteGuid);
        CalendarService svc = BuildCalendarService(token);

        CalendarListEntry entry = svc.CalendarList
                                     .Get(calendarId)
                                     .Execute();

        Cal retVal = new Cal() {
            Id   = entry.Id,
            Name = entry.Summary
        };

        return retVal;
    }

    private async Task<SiteAuthToken> GetToken(Guid siteGuid) {
        SiteAuthToken retVal = await _tokenRepo.GetSiteAuthToken(siteGuid, Constants.OAUTH_PROVIDER_GOOGLE);

        if (retVal == null) {
            throw new ApplicationException($"Could not find a SiteAuthToken for specified site (SiteGuid: {siteGuid})");
        }

        return retVal;
    }

    #endregion
}

1 Ответ

2 голосов
/ 21 мая 2020

Что-то, что мне очень помогло в ситуациях, подобных описанной вами, - это использование Google Developer OAuth Playground . По умолчанию вы можете получить разрешение (и наблюдать за трафиком c), используя сам OAuthPlayground в качестве клиента. Но тогда уловка состоит в том, чтобы набрать go в шестеренке [Настройки] и установить флажок [x] Использовать свои собственные учетные данные OAuth и попытаться авторизовать своего клиента. IMO, это очень полезный инструмент отладки, и я хотел убедиться, что вы о нем знаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...