Authenticating / Refreshing Google API access token and avoiding a "file in use" exception?

Andrew Truckle

This is how I authenticate for using the Google API:

Private Function DoAuthentication(ByRef rStrToken As String, ByRef rParameters As OAuth2Parameters) As Boolean
    Dim credential As UserCredential
    Dim Secrets = New ClientSecrets() With {
        .ClientId = m_strClientID,
        .ClientSecret = m_strClientSecret
    }

    m_Scopes.Add(CalendarService.Scope.Calendar)

    Try
        credential = GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
                                                                 "user", CancellationToken.None,
                                                                 New FileDataStore("XXXXX.Application")).Result()

        If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
            credential.RefreshTokenAsync(CancellationToken.None)
        End If


        ' Create the calendar service using an initializer instance
        Dim initializer As New BaseClientService.Initializer() With {
            .HttpClientInitializer = credential,
            .ApplicationName = "xxx"
        }
        m_Service = New CalendarService(initializer)

        rStrToken = credential.Token.AccessToken.ToString()
        rParameters.AccessToken = credential.Token.AccessToken
        rParameters.RefreshToken = credential.Token.RefreshToken
    Catch ex As Exception
        ' We encountered some kind of problem, perhaps they have not yet authenticated?
        ' Can we isolate that as the exception?
        m_logger.Error(ex, "DoAuthentication")

        Return False
    End Try

    Return True
End Function

And then in my Main:

Dim parameters As New OAuth2Parameters
If (DoAuthentication(strToken, parameters)) Then
    iResult = RESULT_SUCCESS_OAUTH
Else
    Return RESULT_FAILED_OAUTH
End If

It then continues. The problem is that sometimes, even though the "authenticate" succeeds so that it starts to run the rest of the code. that I then get an exception:

2020-11-30 18:47:03.6762|ERROR|GoogleAuthandSync.Program|AddEventsToCalendarXML|System.IO.IOException: The process cannot access the file 'C:\Users\USERNAME\AppData\Roaming\XXXXX.Application\Google.Apis.Auth.OAuth2.Responses.TokenResponse-user' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

How can I authenticate / refresh the token and make sure we are ready to proceed so that this exception stops? It doesn't always happen.

(I renamed the token file for security in the code / error text above).


Should I be using the Await keyword?

enter image description here

If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
    Await credential.RefreshTokenAsync(CancellationToken.None)
End If

Would that make a difference? I notice that in this sample code they use await.

Andrew Truckle

I was encouraged to ask about the issue on GitHub (see discussion).

Turns out that I did not need to be using RefreshTokenAsync in the way that I was. I was able to simplify my code and turn it into an Async method liek this:

Private Async Function DoAuthenticationAsync() As Task(Of Boolean)
    Dim credential As UserCredential
    Dim Secrets = New ClientSecrets() With {
        .ClientId = m_strClientID,
        .ClientSecret = m_strClientSecret
    }

    Try
        credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
                                                             "user", CancellationToken.None,
                                                             New FileDataStore("XXXXX.Application"))

        ' Create the calendar service using an initializer instance
        Dim initializer As New BaseClientService.Initializer() With {
            .HttpClientInitializer = credential,
            .ApplicationName = "XXXXX"
        }

        m_Service = New CalendarService(initializer)

    Catch ex As Exception
        ' We encountered some kind of problem, perhaps they have not yet authenticated?
        ' Can we isolate that as the exception?
        m_logger.Error(ex, "DoAuthentication")

        Return False
    End Try

    Return True
End Function

Then, I had to move all of my code that was in the Main function into a task:

Private Async Function Run() As Task(Of Integer)
    ...
End Function

Finally, I adjusted Main like this:

Public Function Main() As Integer
    Return RunAsync.Result
End Function

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Google Calendar API Token not refreshing

OpenID Connect: Proper way of authenticating user - ID token or Access token? Refreshing ID tokens?

Google OAuth, refreshing access token (grant type)

Google OAuth 403 when refreshing access token

Refreshing an OAuth access token for Microsoft Live API

Web API refresh token not refreshing when access token is expired

Authenticating CloudRun with Access Token for Developers

unauthorized_Client while refreshing google access token

Web API access token not refreshing after it's expired

Call Custom REST API When Refreshing Access Token

Linkedin API access token fetch exception

How do I test refreshing my google access token using a refresh token

Authenticating with Google API using AccountManager

Google Calendar API on Android access token

Google Sheet API Access Token Getting Expired

Access Google spreadsheet API without Oauth token

Google api client php access token not working

Is Google API's access token never expiring?

Google androidpublish api access_token

Retrieving Access and Refresh Token for Google Api

Automatically or manually refreshing access token with flask_client on Google App Engine

Authenticating with Google API library for Java to Google cloud

Why Refreshing access token gets unauthorized?

Refreshing the access token from azure ad

Refreshing an Access Token for Client Credentials Flow

Automating access token refreshing via interceptors in axios

Issue while refreshing access token in angular 5

Question about access token and refresh token in google API

.NET Google API access token failing with no refresh token specified