peburrows / goth

Elixir package for Oauth authentication via Google Cloud APIs
http://hexdocs.pm/goth
MIT License
289 stars 111 forks source link

Goth Timeout on Fetch #151

Closed drewknab closed 1 year ago

drewknab commented 1 year ago

Ran into an issue trying to fetch the token where Goth is reporting that it times out. I've attached a picture of the error I'm receiving and a the code I've written to register Goth. I've tried extending the timeout length to 20 seconds but it didn't seem to make a difference.

2022-12-15 01_40_20-Window

2022-12-15 01_41_25-Window

{
    "type": "service_account",
    "project_id": "{our_project_id}",
    "private_key_id": "{our_private_key_id}",
    "private_key": "{our_private_key}",
    "client_email": "{our_client_email}",
    "client_id": "{our_client_id}",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/{our_client_email}"
}

I've tried to eliminate the credentials file I'm using by verifying that it does work when I use it with a combination with gcloud-cli/curl:

curl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) -H "Content-Type: application/json; charset=utf-8" --data "{
  'input':{
    'text':'I\'ve added the event to your calendar.'
  },
  'voice':{
    'languageCode':'en-gb',
    'name':'en-GB-Standard-A',
    'ssmlGender':'FEMALE'
  },
  'audioConfig':{
    'audioEncoding':'MP3'
  }
}" "https://texttospeech.googleapis.com/v1/text:synthesize"

It also seems to work if I use:

credentials = "google_creds.json" |> File.read!() |> Jason.decode!()
{:ok, _} = Goth.start_link(name: MyApp.Goth, source: {:service_account, credentials, []})
Goth.fetch!(MyApp.Goth)

I'm not really sure why/how that would be operating differently from registering with the application supervisor.

drewknab commented 1 year ago

After doing some additional digging, I've tracked the issue down to this set of functions:

2022-12-16 21_25_44-Window 2022-12-16 21_33_41-Window

Resulting in this error

2022-12-16 21_24_28-Window

Not really sure how to proceed further than that.

It looks like the callback to send the request via finch looks like so:

{#Function<3.132772677/1 in Goth."-fun.__finch__/1-">, [],
 [
   method: :post,
   url: "https://www.googleapis.com/oauth2/v4/token",
   headers: [{"content-type", "application/x-www-form-urlencoded"}],
   body: "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={redacted_jwt}"
 ]}
binarytemple commented 1 year ago

Similar here, in my case the depreciated Goth.Token.for_scope works but Goth.fetch does not, haven't investigated whether there is a functional or just a semantic difference between the two.

Erlang/OTP 25 [erts-13.1.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.14.3) - press Ctrl+C to exit (type h() ENTER for help)
(search)`scope =': scope = "https://www.googleapis.com/auth/pubsub"
"https://www.googleapis.com/auth/pubsub"
(search)`Goth': Goth.fetch(scope)                           
** (exit) exited in: GenServer.call({:via, Registry, {Goth.Registry, "https://www.googleapis.com/a
uth/pubsub"}}, :fetch, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with
 the given name, possibly because its application isn't started
    (elixir 1.14.3) lib/gen_server.ex:1027: GenServer.call/3
    iex:2: (file)
iex(2)> Token.for_scope(scope)
** (UndefinedFunctionError) function Token.for_scope/1 is undefined (module Token is not available
)
    Token.for_scope("https://www.googleapis.com/auth/pubsub")
    iex:2: (file)
iex(2)> Goth.Token.for_scope(scope)
warning: Goth.Token.for_scope/1 is deprecated. Use Goth.fetch/1 instead

{:ok,
 %Goth.Token{
   token: "that would be telling :-)",
   type: "Bearer",
   scope: "https://www.googleapis.com/auth/pubsub",
   sub: nil,
   expires: 1685901667,
   account: :default
 }}
wojtekmach commented 1 year ago

Goth.fetch/1 accepts name of the Goth server started as part of your supervision tree, not the scope.

Unfortunately we cannot provide better error message since the name of the server can be any term. (Thanks to registry)

wojtekmach commented 1 year ago

I'm going to go ahead and close this because it's not actionable at the moment but feel free to continue the conversation. Any ideas how to improve DX are welcome!