JRQ JRQ - 1 month ago 7x
Ruby Question

Trouble with Google Apps API and Service Accounts in Ruby

I'm having some trouble getting the sample code for instantiating a Drive Service Account working. I've set up the service account in the API console as directed and included the scope for the 'https://www.googleapis.com/auth/drive', but running this generates the following error: "Authorization failed. Server message: (Signet::AuthorizationError)".

Oddly, if I omit the user_email address it doesn't generate an error.

My objective is to be able to do an audit on all the files stored on the organization's Drive, and it's my understanding that using a service account would be the way to get a listing of all the files stored.

Have I missed some special setting on the server side for this?

require 'google/api_client'

## Email of the Service Account #
SERVICE_ACCOUNT_EMAIL = '<service account email>@developer.gserviceaccount.com'

## Path to the Service Account's Private Key file #
SERVICE_ACCOUNT_PKCS12_FILE_PATH = '<private key file>-privatekey.p12'

def build_client(user_email)
key = Google::APIClient::PKCS12.load_key(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'notasecret')
asserter = Google::APIClient::JWTAsserter.new(SERVICE_ACCOUNT_EMAIL, 'https://www.googleapis.com/auth/drive', key)
client = Google::APIClient.new

client.authorization = asserter.authorize(user_email)
return client

client = build_client("<users email address>")


This looks to me like you are using an older example. I think that's how you used to do it about a year ago. Back in late 2012 that method of setting up the app was deprecated because Signet was updated to handle all aspects of the OAuth2 setup.

Here is the code I generally use to create a service account. You can tweak it to fit into your method.

client.authorization = Signet::OAuth2::Client.new(
 :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
 :audience => 'https://accounts.google.com/o/oauth2/token',
 :scope => "https://www.googleapis.com/auth/drive",
 :issuer => "<service account email>@developer.gserviceaccount.com",
 :signing_key => Google::APIClient::KeyUtils.load_from_pkcs12("<private key file>-privatekey.p12", "notasecret"),
 :person => "<users email address>")

If you are still having issues let me know and I'll see if I can help.