In my application I am using Google API V 3.0 .Net library with Google OAuth2 to synchronize Google calender and outlook calender. I am using below code to get the Google.Apis.Calendar.v3.CalendarService service object. During authentication I stored the Json file and from that I am requesting for Google.Apis.Auth.OAuth2.UserCredential object.
private Google.Apis.Auth.OAuth2.UserCredential GetGoogleOAuthCredential()
{
GoogleTokenModel _TokenData = new GoogleTokenModel();
String JsonFilelocation = "jsonFileLocation;
Google.Apis.Auth.OAuth2.UserCredential credential = null;
using (var stream = new FileStream(JsonFilelocation, FileMode.Open,
FileAccess.Read))
{
Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.Folder = "Tasks.Auth.Store";
credential = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(stream).Secrets,
new[] { Google.Apis.Calendar.v3.CalendarService.Scope.Calendar },
"user",
CancellationToken.None,
new FileDataStore("OGSync.Auth.Store")).Result;
}
return credential;
}
Requesting for Service object code is :
Google.Apis.Calendar.v3.CalendarService _V3calendarService = new Google.Apis.Calendar.v3.CalendarService(new Google.Apis.Services.BaseClientService.Initializer()
{
HttpClientInitializer = GetGoogleOAuthCredential(),
ApplicationName = "TestApplication",
});
Above code works fine to get the Calendarservice object. My question is, my Json file has refresh and access tokens. how the above code handles refresh token to obtain the service when access token expired? Because I need to call the Calendarservice object frequently, I like to implement singleton pattern for calenderService object. How to get Calendarservice without calling GetGoogleOAuthCredential frequently? Any help/guidance is appreciated.
For me, client library did not do the refreshing, not even creating the refresh token.
I check whether the token is expired and refresh. (Token has a 1hour life time). credential.Token.IsExpired will tell you whether it is expired, credential.Token.RefreshToken(userid) will refresh the necessary token.
Spent the last two days figuring this out myself. The library does not refresh the tokens automatically unless you specify "access_type=offline".
https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth
I'm gonna paste the code I'm using and if there is anything you don't understand, just ask. I have read so many posts and I litteraly got this working right now so there is some commented code and it has not been refactored yet. I hope this will help someone. The NuGet packages I'm using are these:
Google.Apis.Auth.MVC
Google.Apis.Calendar.v3
Code:
AuthCallbackController:
}
Method for Controller calling Google API
Derived class of FlowMetadata
Entity framework 6 DataStore class
Derived class for GoogleAuthorizationCodeFlow. Enabling long-lived refresh token that take care of automatically "refreshing" the token, which simply means getting a new access token.
https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth
GoogleAuthItem is used with EFDataStore
That's the butty of the client library! this magic is done for you automatically :)
UserCredential implements both IHttpExecuteInterceptor and IHttpUnsuccessfulResponseHandler. so whenever the access token is going to be expired, or is already expired, the client makes a call to the authorization server to refresh the token and get a new access token (which is valid for the next 60 minutes).
Read more about it at https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#credentials