简体   繁体   中英

Missing token endpoint URI while using a valid access_token

All of a sudden (possibly a gem update?) calling the Google api stopped woking. I was already able to retrieve the gmail threads, but no longer.

What I have so far:

I am able to retrieve a refresh token for offline access. So I have the refresh and access tokens stored. Great.

Now I want to retrieve the profile info. Here is what I do (mind you this used to work just fine!)

I will add a puts after every line below to show you what we get...

module AuthHelper
  require 'google/api_client/client_secrets'
  ...
  client = Signet::OAuth2::Client.new(access_token: user.gmail_access_token)
  service = Google::Apis::GmailV1::GmailService.new
  service.authorization = client
  service.get_user_profile('me') # retrieve threads
  ...
end

Let me print the responses I get:

CLIENT : --- !ruby/object:Signet::OAuth2::Client
authorization_uri: 
token_credential_uri: 
client_id: 
client_secret: 
code: 
expires_at: 
expires_in: 
issued_at: 
issuer: 
password: 
principal: 
redirect_uri: 
scope: 
state: 
username: 
expiry: 60
extension_parameters: {}
additional_parameters: {}
access_token: ya29.Ci8QA3K_mLh1vB_55bSnGVB66yLwzkxClM8yCI5qmmZo6n0JzjVNA7Q6EAOm3qQeGw

SERVICE : --- !ruby/object:Google::Apis::GmailV1::GmailService
root_url: https://www.googleapis.com/
base_path: gmail/v1/users/
upload_path: upload/gmail/v1/users/
batch_path: batch
client_options: !ruby/struct:Google::Apis::ClientOptions
  application_name: unknown
  application_version: 0.0.0
  proxy_url: 
  use_net_http: false
request_options: !ruby/struct:Google::Apis::RequestOptions
  authorization: 
  retries: 0
  header: 
  timeout_sec: 
  open_timeout_sec: 20

SERVICE.authorization : --- !ruby/object:Signet::OAuth2::Client
authorization_uri: 
token_credential_uri: 
client_id: 
client_secret: 
code: 
expires_at: 
expires_in: 
issued_at: 
issuer: 
password: 
principal: 
redirect_uri: 
scope: 
state: 
username: 
expiry: 60
extension_parameters: {}
additional_parameters: {}
access_token: ya29.Ci8QA3K_mLh1vB_55bSnGVB66yLwzkxClM8yCI5qmmZo6n0JzjVNA7Q6EAOm3qQeGw
{"message":"Sending HTTP get https://www.googleapis.com/gmail/v1/users/me/profile?","@timestamp":"2016-06-28T19:52:38.974-07:00","@version":"1","severity":"DEBUG","host":"ben.local"}
{"message":"Caught error Missing token endpoint URI.","@timestamp":"2016-06-28T19:52:38.976-07:00","@version":"1","severity":"DEBUG","host":"ben.local"}
{"message":"Error - #\u003cArgumentError: Missing token endpoint URI.\u003e\n","@timestamp":"2016-06-28T19:52:38.977-07:00","@version":"1","severity":"DEBUG","host":"ben.local"}
GOT EXCPETION: Missing token endpoint URI.

I should not see this: "Missing token endpoint URI". When you use an access_token, it should handle authorization, right? As I said, this was not an issue before.

Although I did not think it was needed, I addded the endpoint URI ' https://accounts.google.com/o/oauth2/auth ' from clients_secret.json and got authorization failed.

What AM I missing? :)

The Google documentations cut out the part that should explain how to access their api once you actually got an access token out of ALL their online tutorials! Here:

  1. https://github.com/google/google-api-ruby-client
    • Stop explaining how to authenticate with this comment: "drive.authorization = ... # See Googleauth or Signet libraries" So we're heading over to Signet, because Googleauth is cryptic.
  2. https://github.com/google/signet
    • Guides you on how to obtain an access token, then stops explaining what to do with it.
  3. https://developers.google.com/identity/protocols/OAuth2WebServer#offline
    • Google's API documentation, shows you how to get the access token, even an offline access with refresh (which I have), then NO explanation as to what to do with the access token.

I finally found an answer here: https://github.com/google/google-api-ruby-client/issues/296

Basically create a new class for the access token (I added it to my lib folder) and follow the rest of what is described in the link above. Only replace .authenticate with .authorize, I guess it's a mistake. Hope this helps someone.

Below line save mine time. It is working fine now

Add:

client.expires_in = Time.now + 1_000_000

After:

client = Signet::OAuth2::Client.new(access_token: user.gmail_access_token)

Copying code from the github issue page to save you a click:

require 'google/apis/sheets_v4'
require 'google/apis/drive_v2'
require 'googleauth'

class GoogleService
  attr_accessor :sheets, :drive

  def initialize(user)
    auth = Signet::OAuth2::Client.new(
  token_credential_uri: 'https://oauth2.googleapis.com/token',
  client_id: ENV["GOOGLE_CLIENT_ID"],
  client_secret: ENV["GOOGLE_CLIENT_SECRET"],
  refresh_token: user.refresh_token
)
auth.fetch_access_token!
user.update(token: auth.access_token)


sheets = Google::Apis::SheetsV4::SheetsService.new
sheets.authorization = auth
@sheets = sheets

drive = Google::Apis::DriveV2::DriveService.new
drive.authorization = auth
@drive = drive

end end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM