I've carefully reviewed Steve Bazyl's presentation at https://www.youtube.com/watch?v=iK14bfd6qhs and relevant API docs on google. I'm using the Service Account email id for my gmail account, and am using the private key downloaded from the Console.
But when I run the test client modeled after the one Steve showed in his presentation I consistently get
Signet::AuthorizationError:
Authorization failed. Server message:
{
"error" : "invalid_grant"
}
I get the same error message if I add garbage letters to the email or scope passed to JWTAsserter. Clearly something wrong but I can't seem to figure out how to troubleshoot this.
Here's the client code I'm running (in a rails rspec file):
client = Google::APIClient.new
key_file = '/Users/stu/projects/br/rails-app/######-privatekey.p12'
key = Google::APIClient::KeyUtils.load_from_pkcs12(key_file, 'notasecret')
Rails.logger.info "Private key? #{key.private?}"
asserter = Google::APIClient::JWTAsserter.new(
'#####-#######[email protected]',
"https://www.googleapis.com/auth/calendar",
key)
client.authorization = asserter.authorize()
I'm pretty well stuck, would definitely appreciate any troubleshooting advice.
Thanks!
Update
Thanks for sharing code that works for you Jack.
I've gone to my site's dev console and created a service account client p12 key. I then went to the site's Admin Console and added my client id granting site-wide authorization to the calendar API
In the Admin Console after adding the authorization it looks like this: XXXXXXXXXXXhnq.apps.googleusercontent.com Calendar (Read-Write) https://www.googleapis.com/auth/calendar
I downloaded the p12 key and used it in the code structure you provided. I also tried with the approach from Steve Bazyl's presentation:
asserter = Google::APIClient::JWTAsserter.new(
"[email protected]",
"https://www.googleapis.com/auth/calendar",
key)
client.authorization = asserter.authorize("[email protected]")
In both cases I get the same output as before:
Signet::AuthorizationError:
Authorization failed. Server message:
{
"error" : "invalid_grant"
}
I get that same output if I type in junk instead of "XXXXs://www.googleapis.com/auth/calendar". The key is valid, and while it's clear I'm doing something wrong, I can't find any clues in the API or google about how to tell what it is.
Any ideas how to troubleshoot?
Have you given service account access to your Google Apps account? You can find out how to that here: https://developers.google.com/+/domains/authentication/delegation#delegate_domain-wide_authority_to_your_service_account
Following code works for me:
key = Google::APIClient::KeyUtils.load_from_pkcs12('tmp/##########-privatekey.p12', 'notasecret')
client = Google::APIClient.new({:application_name => "example-app", :application_version => "1.0"})
client.authorization = Signet::OAuth2::Client.new(
:person => '[email protected]',
: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.readonly',
:issuer => '[email protected]',
:signing_key => key)
client.authorization.fetch_access_token!
drive = client.discovered_api('drive', 'v2')
result = client.execute(api_method: drive.files.list)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With