Google日历返回无效授权

问题描述 投票:6回答:1

我有一个客户正在尝试从我们的Web应用程序访问他们的日历。一切对我们所有其他客户都有效,所以我不确定这里有什么不同,除了该客户在澳大利亚并且使用非gmail.com电子邮件地址。

客户可以授权我们的应用程序,我们确实为用户获得了oauth令牌。我们要求日历访问权限,并且客户已授予它访问权限。当我们请求所有日历的列表时,我们会收到无效的授权消息。

下面是我们用于访问其日历的代码。被调用的方法是GetAllWritableCalendars。

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

    private const string APPNAME = "SomeAppName";

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

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

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

        return retVal;
    }

    #endregion
c# .net google-calendar-api
1个回答
3
投票

凭据是从Google您的应用程序的授权,以使用您已设置的范围,可以将其放在数据库,如果每次将新作用域添加到应用程序时都进行更新。

Access Token是从用户您的应用程序>>的授权,以获取Google数据(在这种情况下为calendar )。生命周期有限,因此无法保存到数据库中。

Refresh Token

是允许您的应用程序为客户端获取更多令牌的令牌。它的寿命也有限。

有关更多信息,请参见:Using OAuth 2.0 to Access Google APIs

每次更改范围或添加更多范围时,都必须重新生成凭据。每个客户端每个用户帐户有50个刷新令牌,请参阅Token expiration。因此,将令牌存储在数据库中毫无意义,因为它们将在某个时候被弃用,如果您有51个客户端,则第一个令牌将被弃用。

检查:

  1. 如何在数据库中进行设置
  2. 如果您正确地更新令牌
  3. 如果您为用户使用正确的令牌
  4. 您可以删除所有令牌(NO CREDENTIALS

),并且您当前的用户将只需要通过同意屏幕并再次允许它,他们就不会失去连接。
© www.soinside.com 2019 - 2024. All rights reserved.