Reputation: 3
I am trying to set up a class that can wrap around the .NET Google API so that I can use an Access Token that I have previously obtained to access a user's Google Drive. As of right now, I am just trying to get it to work so that I do not require a Refresh Token (more on that in a second). The ultimate goal is for somebody to go through a web page I have set up to authenticate where I obtain both an Access Token and a Refresh Token by directly calling to the Google Rest API (which I store in a database). They can then request to upload/download files onto their Drive on a different page which will first obtain the appropriate information from the database and then use the .NET Google API Library when accessing Drive.
However, when I attempt to access their Drive I get the the following error:
The access token has expired and could not be refreshed. Errors: refresh error, refresh error, refresh error
I know that the Access Token is valid because I obtain it only seconds earlier during my testing. Here is my code for setting up the Drive Service:
' NOTE: Code altered for brevity
Public Sub Initialize(accessToken As String)
' Set up the client secret information based on the default constants
Dim clientSecrets As New ClientSecrets()
clientSecrets.ClientId = DEFAULT_CLIENT_ID
clientSecrets.ClientSecret = DEFAULT_CLIENT_SECRET
' Set up a token based on the token data we got
' NOTE: Is it OK to leave some strings as NULL?
Dim token As New Responses.TokenResponse()
token.AccessToken = accessToken
token.RefreshToken = ""
token.TokenType = "Bearer"
token.IssuedUtc = DateTime.Now
token.ExpiresInSeconds = 3600
token.Scope = "drive"
token.IdToken = ""
' Set up a flow for the user credential
Dim init As New GoogleAuthorizationCodeFlow.Initializer()
init.ClientSecrets = clientSecrets
init.Scopes = New String() {DriveService.Scope.Drive}
init.Clock = Google.Apis.Util.SystemClock.Default
' Set up everything else and initialize the service
Dim baseInit As New BaseClientService.Initializer()
baseInit.HttpClientInitializer = New UserCredential(New GoogleAuthorizationCodeFlow(init), "user", token)
baseInit.ApplicationName = APP_NAME
_service = New DriveService(baseInit)
End Sub
Shortly after that, I then use the following code to request a folder so I can check to see if it exists or not.
Private Function GetDriveFolder(folderPath As String, ByRef folderIds As String(), Optional createMissingFolders As Boolean = False, Optional parentFolderId As String = "root") As Data.File
Dim creatingFolderPath As Boolean = False
Dim currentFolder As Data.File = Nothing
Dim folderPathSplit As String() = folderPath.Replace("/", "\").Trim("\").Split("\")
Dim folderIdList As New List(Of String)
folderIds = {}
' Loop through each folder in the path and seek each out until we reach the end
For x As Integer = 0 To folderPathSplit.Length - 1
Dim result As FileList = Nothing
If Not creatingFolderPath Then
' Build a list request which we will use to seek out the next folder
Dim request As FilesResource.ListRequest = _service.Files.List()
request.Q = "mimeType='application/vnd.google-apps.folder' and name='" & folderPathSplit(x) & "'"
If currentFolder Is Nothing Then
request.Q &= " and '" & EscapeDriveValue(parentFolderId) & "' in parents"
Else
request.Q &= " and '" & EscapeDriveValue(currentFolder.Id) & "' in parents"
End If
request.Spaces = "drive"
request.Fields = "files(id, name)"
' Execute the search, we should only get a single item back
' NOTE: Error thrown on this request
result = request.Execute()
End If
' So on.....
So, I'm just trying to get it to work with only the Access Token for the time being because if it ends up getting refreshed I'll need to know so that I can update my database. However, if I do include the Refresh Token I get the following error:
Error:"unauthorized_client", Description:"Unauthorized", Uri:""
I'm guessing this has something to do with the way I have configured my application through the Dev Console but if I authenticate through the Google API Library by having it launch a browser to get my credentials everything works fine. So, I'm really not sure where to go from here as I haven't found anybody having similar problems and the guides don't cover specifying your own Access Token.
Also, as a quick note this is the URL I am using when having the user authenticate:
String.Format("https://accounts.google.com/o/oauth2/v2/auth?client_id={0}&state={1}&redirect_uri={2}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&include_granted_scopes=true&prompt=select_account%20consent&response_type=code", GOOGLEAPI_CLIENTID, validateState, redirectUri)
Thanks for the help!
Upvotes: 0
Views: 1435
Reputation: 1705
If you have an access-token then the simplest way to create a google credential is to use the GoogleCredential.FromAccessToken() method passing in your access token.
This returns you a GoogleCredential
instance which you can use to set the HttpClientInitializer
property when building the DriveService
.
If you then still get an error when accessing the drive service, then it's likely there's something incorrect in how you are asking for the access-token.
Upvotes: 1