User Principal OAuth2 (Three Legged, Authorization Code) does not include Refresh Token(s)
YvanJAquino opened this issue · 3 comments
Hi there,
I'm seeing some unexpected behavior while interacting with oauth2.Config & oauth2.Token objects.
My client targets a Google Cloud OAuth Client ID (via the Oauth Consent Screens service AKA OAuth Brands). My client uses a web app type credential which exists in the following format:
{
"web": {
"client_id": "...",
"project_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_secret": "...",
"redirect_uris": [
"http://localhost",
"https://oauth2-authorizer-service"
]
}
}
Creating a config from this always works fine. I then update the redirect URL, generate a randomized state string, and generate an AuthCodeURL, specifying the oauth2.AccessTypeOffline option.
/ Local Fetch token initiates a request from the localhost; the user is responsible for
// providing the state and auth code.
func (tm *TokenManager) LocalFetchToken(ctx context.Context) (err error) {
// Generate an opaque identifier by hex-digesting random bytes.
stateBuf := make([]byte, 32)
if _, err = rand.Reader.Read(stateBuf); err != nil {
return
}
oauth_state := hex.EncodeToString(stateBuf)
authCodeURL := tm.config.AuthCodeURL(oauth_state, oauth2.AccessTypeOffline)
fmt.Printf("Please go to the following link in your browser to generate an auth code:\n\t%s\n", authCodeURL)
var code, state string
fmt.Print("Authorization code:")
fmt.Scanln(&code)
fmt.Print("\nAuthorization state:")
fmt.Scanln(&state)
if oauth_state != state {
return fmt.Errorf("states do not match")
}
token, err := tm.config.Exchange(ctx, code)
if err != nil {
return
}
fmt.Printf("Token Refresh Token: %s\n", token.RefreshToken)
tm.token = token
return
}
This is not producing Refresh tokens even with the oauth2.AccessTypeOffline option. In the past, this used to issue Refresh tokens.
According to the documentation on oauth2.AccessTypeOffline documentation:
// AccessTypeOnline and AccessTypeOffline are options passed
// to the Options.AuthCodeURL method. They modify the
// "access_type" field that gets sent in the URL returned by
// AuthCodeURL.
//
// Online is the default if neither is specified. If your
// application needs to refresh access tokens when the user
// is not present at the browser, then use offline. This will
// result in your application obtaining **a refresh token the**
// **first time your application exchanges an authorization**
// **code for a user.**
AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
Regards,
I created a new client and it now has a button to enable token renewal
It's worth noting that I need to prompt for consent - IE I need to do the ENTIRE flow.