I'm trying to build an application which reads and writes to a private Google Spreadsheet. For this I need to use Google OAuth2.0 .
My problem is that I lose access after 1 hour. I assume this means that the refresh token is not being used correctly. Here is my code for handling authentication:
public static SpreadsheetsService AuthenticateOauth(string clientId, string clientSecret, string userName)
{
string[] scopes = new string[] { DriveService.Scope.Drive, // view and manage your files and documents
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveAppsReadonly,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveMetadataReadonly,
DriveService.Scope.DriveReadonly,
"https://spreadsheets.google.com/feeds",
"https://docs.google.com/feeds"
};
try
{
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, new FileDataStore("MY.APP.Auth.Store")).Result;
SpreadsheetsService service = new SpreadsheetsService(My App");
var requestFactory = new GDataRequestFactory("My App");
requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));
service.RequestFactory = requestFactory;
return service;
}
catch (Exception ex)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm") + ": An authentication error occurred: " + ex.InnerException);
return null;
}
}
How do I go about making the refresh token being used correctly?
You are using the current Google .NET client library to authenticate. When you create a service, it normally will automatically refresh your access token when needed. However, you are sending an access token to an old Gdata library, which doesn't automatically refresh it.
If you create a drive service and run a dummy request against it once an hour it will refresh your access token for you when needed.
var service = new DriveService(new BaseClientService.Initializer() {HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",});
// Dummy request example:
FilesResource.ListRequest list = service.Files.List();
list.MaxResults = 1;
list.Q = "title=dummysearch";
FileList dummyFeed = list.Execute();
// End of Dummy request