Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

google/apis/drive_v2 authentication on new google Drive authentication. I also hope to avoid frustration with google-api-client

First my question is about getting google drive_v2 authentication working and creating new files etc with my rails 4.2 app. I have the rails app with devise/omniauth2 and google working just fine. I have activated in the google dev console both web auth and google API auth. Both client secrets are downloaded and working.

So having said that. I need my rails app in offline access to be able to use, create, and delete goole Docs and Spreadsheets. I've set the scope for .drive, setup offline access etc.

I've EVEN written code that works just fine if I go in the google playground and get a new access token to use.

My first problem is the ability to get my refresh_token and authenticate or get a new one using the google-api-client (version 0.9pre3 so people aren't confused)

In order to use the new google api I needed to comment out google drive since it seemed that all the APIs where combined into the client.

gem 'omniauth-google-oauth2'
#gem 'google_drive'
gem 'google-api-client', '0.9.pre3'

I'm stuck on the authentication/authorization step and I'm feeling rather dumb about it.

So sample code on the github repo for the api here, or the google dev site here lead me to believe this works.

require 'google/apis/drive_v2'

Drive = Google::Apis::DriveV2 # Alias the module
drive = Drive::DriveService.new
drive.authorization = authorization # See Googleauth or Signet libraries

or

drive.authorization = Google::Auth.get_application_default([Drive::AUTH_DRIVE])

of course what is authorization? According to the docs I go here.

Running the example code below: require 'googleauth'

Get the environment configured authorization

scopes =  ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute']
authorization = Google::Auth.get_application_default(scopes)

leads to:

authorization = Google::Auth.get_application_default(scopes)
RuntimeError: Could not load the default credentials. Browse to
https://developers.google.com/accounts/docs/application-default-credentials
for more information
from /Users/prussiap/.gem/ruby/2.2.0/gems/googleauth-0.4.2/lib/googleauth.rb:116:in `get_application_default'

Probably due to my confusion or stupidity.

The other method displayed in the google dev site docs linked above and the service accounts seem like the way to go aka here.

But nothing works. I've seen a smattering of these client_secrets too

client_secrets = Google::APIClient::ClientSecrets.load
authorization = client_secrets.to_authorization

of course that .load breaks on it's own as it expects a magical file path or file name but nothing I fed it worked

Any sample code that allows me to either use my client_secret for service account or oauth2 (web app) but without any fancy redirects would be fantastic and really help..

Now for others new to the google api please read below. I feel like I'm dumb for not seeing this or noticing it but maybe this info can help you guys when I raised the issue on the github repo I was confused..

Apparently the google API-client for ruby is totally different from < 0.9pre1 or greater then that. So is the documentation.

SO if you are reading this type of code and are reading these docs:

require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'

APPLICATION_NAME = 'Drive API Quickstart'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials',
                             "drive-quickstart.json")
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly

Then you're using < 0.9pre1 (I'm pretty sure)

Otherwise you see my code above with the drive_v2, then remove your google_drive gem because it's rolled into one api and read this doc.

I hope this helps others.

And any help on my authentication problem including using service vs api vs other type of account with some sample code for making authentication and then authenticating with a refresh token. Would be fantastic.

like image 566
prussiap Avatar asked Aug 12 '15 21:08

prussiap


People also ask

How do I get authentication for Google Drive?

Procedure. Go to Google Developers OAuth Playground. Click OAuth 2.0 Configuration and select Use your own OAuth credentials check box, enter the OAuth client ID and client secret you have already created in the OAuth Client ID and OAuth Client secret fields respectively.

How do I fix Error 403 user limit exceeded?

Resolve a 403 error: Daily limit exceeded This error appears when the application's owner has set a quota limit to cap usage of a particular resource. To fix this error, remove any usage caps for the "Queries per day" quota.


2 Answers

I just ran into the same problem -- I haven't resolved it totally, but I got past this particular error by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable, and pointing it to a service account key file -- this is not the same as the client_secrets that worked for earlier versions of the API.

Google's instructions in their documentation: Application Default Credentials: How They Work lays this out, but the important note is that "service account" is a different auth method than client_secrets.

First, go to the Developers Console API Credentials page for your project and pick an existing/create a new "Service account key". Assume we've put the downloaded .json file in /path/to/svc_acct_auth.json

In your ruby code, add the line:

ENV["GOOGLE_APPLICATION_CREDENTIALS"] = '/path/to/svc_acct_auth.json'

That should get the service to return properly and get you past that runtime error. Granted, I'm still having trouble executing the calls I need through this auth system, but hey! I've graduated to newer & better error messages.

like image 141
Matt Cahill Avatar answered Dec 02 '22 22:12

Matt Cahill


Here is code I used to save db backups to google drive, maybe it would help:

require 'google/apis/drive_v2'
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = "#{Rails.root}/config/google_api_credentials.json"
drive = Google::Apis::DriveV2::DriveService.new
drive.authorization = Google::Auth.get_application_default([Google::Apis::DriveV2::AUTH_DRIVE_FILE])

metadata = {title: File.basename(archive_path, '.sql.bz2')}
file = drive.insert_file(metadata, upload_source: archive_path, content_type: 'application/x-bzip2')

perm_id = drive.get_permission_id_for_email('[email protected]')
perm = Google::Apis::DriveV2::Permission.new(role: 'writer', id: perm_id.id, type: 'user')
drive.insert_permission(file.id, perm)
like image 28
Lev Lukomsky Avatar answered Dec 02 '22 23:12

Lev Lukomsky