我有一个客户正在尝试从我们的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
凭据是从Google到您的应用程序的授权,以使用您已设置的范围,可以将其放在数据库,如果每次将新作用域添加到应用程序时都进行更新。
Access Token是从用户到您的应用程序>>的授权,以获取Google数据(在这种情况下为calendar )。生命周期有限,因此无法保存到数据库中。
Refresh Token
是允许您的应用程序为客户端获取更多令牌的令牌。它的寿命也有限。有关更多信息,请参见:Using OAuth 2.0 to Access Google APIs
每次更改范围或添加更多范围时,都必须重新生成凭据。每个客户端每个用户帐户有50个刷新令牌,请参阅Token expiration。因此,将令牌存储在数据库中毫无意义,因为它们将在某个时候被弃用,如果您有51个客户端,则第一个令牌将被弃用。
检查:
您可以删除所有令牌(NO CREDENTIALS