1

I want to get the Oauth token from the GCP client credentials. Reference

package main

import (
    "fmt"
    "io/ioutil"
    "log"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
)

func main() {
    data, err := ioutil.ReadFile("/Users/supreetdeshpande/Downloads/esp-rainmaker-97663-2f539a842d10.json")
    if err != nil {
        log.Fatal(err)
    }
    conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/homegraph")
    if err != nil {
        log.Fatal(err)
    }

    client := conf.Client(oauth2.NoContext)
    response, err := client.Get("...")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(response)
}

I have downloaded the credentials and they work well with the Google Actions Test suite. I tried this code but I'm getting 2020/06/02 01:58:56 Get ...: unsupported protocol scheme ""

Often these errors seem to arise due to incorrect token URLs. My configured URI is https://oauth2.googleapis.com/token which conforms as stated here.

Works well with oauth2l fetch --credentials ~/Downloads/esp-rainmaker-97663-2f539a842d10.json --scope https://www.googleapis.com/auth/homegraph

To confirm the scheme I replaced ("...") above with the actual URL,
response, err := client.Get("https://oauth2.googleapis.com/token")
It resulted in the below error

&{404 Not Found 404 HTTP/2.0 2 0 map[Alt-Svc:[h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"] Content-Length:[0] Content-Type:[text/html] Date:[Tue, 02 Jun 2020 18:43:01 GMT] Server:[scaffolding on HTTPServer2] X-Content-Type-Options:[nosniff] X-Frame-Options:[SAMEORIGIN] X-Xss-Protection:[0]] {0xc0002a6280} 0 [] false false map[] 0xc00011e300 0xc0000b2370}

Had logged an issue here as well. Is there something I could be missing on my part?

Sprite
  • 350
  • 1
  • 5
  • 17
  • It's not clear that the error is related to authentication. Are you sure the URL passed to Get includes the scheme (i.e. http:// or https://)? – Peter Jun 02 '20 at 13:18
  • Yes, it reads from the config file which has the https:// scheme. – Sprite Jun 02 '20 at 20:00
  • Snippet from the JSON file - `"token_uri": "https://oauth2.googleapis.com/token",` Tried printing the `client` before the Get call and it did print the correct URL too. – Sprite Jun 02 '20 at 20:06
  • 1
    So changing the URL fixed the error then. You're not supposed to call the token endpoint yourself. The client will do that transparently as required. Requests to the token endpoint are POST requests, so getting a 404 response isn't too surprising (but again, don't worry about it). Just make the request that requires authorization using a URL including the scheme. – Peter Jun 03 '20 at 04:57

2 Answers2

1

Okay, I realized that the http client is not to be used to connect directly. JWT offers another API, tokensource which should be used.

This reference was incorrect as I was confused with the goDoc's service account example.

The code should look like this->

func GoogleAccessTokenFromJSON(secret_json string, scope string) (string, error){
  data, err := ioutil.ReadFile(secret_json)
  if err != nil {
      return "",err
  }

  conf, err := google.JWTConfigFromJSON(data, scope)
  if err != nil {
      return "",err
  }

  res := conf.TokenSource(oauth2.NoContext)
  token,err := res.Token()
  if err != nil {
      return "",err
  }

  return token.AccessToken, err
}

Credits: https://github.com/golang/oauth2/issues/280

Sprite
  • 350
  • 1
  • 5
  • 17
0

There is also a possibility of missing permissions which was my case.

conf.Subject = "email"

email = Email you want the svc account to pretend to be
Add this to your config and client.Get(..) works!