go-cfclient icon indicating copy to clipboard operation
go-cfclient copied to clipboard

How should we handle token expiration? Not sure if go-cfclient handles this for us.

Open djvdorp opened this issue 7 years ago • 3 comments

I am fairly new to programming in Golang, so I am sorry if I am doing something wrong myself here, and I will try to describe this as concise as possible:

I have a Golang web app with an endpoint that uses a method to retrieve information from CF, this is the snippet in pseude-code (no imports):

// main.go
func GetCfClient() (client *cfclient.Client, err error) {
	new_client, err := cfclient.NewClient(&cfclient.Config{
		ApiAddress: cfAPI,
		Username:   cfUser,
		Password:   cfPassword,
		HttpClient: myHttpClient,
	})

	if err != nil {
		return client, errors.New(fmt.Sprintf("Failed to create CfClient:", err))
	}
	return new_client, nil
}

var client, client_err = GetCfClient()

func AppByGuid(cfAppGuid string) (app cfclient.App, err error) {
	if client_err != nil {
                return cfclient.App{}, client_err
        }

        cfApp, err := AppByGuid(cfAppGuid)
        if err != nil {
                return cfclient.App{}, err
        }
        return cfApp, nil
}

As you can see, I am putting the var client in the file blocks scope, according to http://www.tapirgames.com/blog/golang-block-and-scope. I am doing this because it feels more sensible to have a "global" client available, instead of creating a new one for every request (the request gets handled by the AppByGuid function, but that code is irrelevant for here). What I am seeing is that I sometimes get this:

oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"invalid_token","error_description":"The token expired, was revoked, or the token ID is incorrect: XXX"})

Which I think happens when my CF authorization is expired. How should I handle this instead?

djvdorp avatar Feb 08 '18 10:02 djvdorp

Hi @djvdorp, sounds like this is the same issue. https://github.com/cloudfoundry-community/go-cfclient/issues/34. You should be able to use GetToken to refresh your oath token. I guess then its up to you how you want to capture your error and wrap it up.

srbry avatar Feb 12 '18 13:02 srbry

Hi @srbry, thanks a lot, seems that I totally missed that issue, sorry for that. I will read up there!

djvdorp avatar Feb 12 '18 13:02 djvdorp

our application is now set up to build a new client every 24 hours to get a new refresh token before the old one expires.

func newApiClient() {
	...
	go func() {
		c := time.Tick(24 * time.Hour)
		for range c {
			apiClient.resetCloudFoundryClient()
		}
	}()
}
func (s *ApiClient) resetCloudFoundryClient() {
	client, err := cfclient.NewClient(&s.clientConfig)
	if err != nil {
		panic (err.Error())
	}
	s.client = client
}

but i am a bit confused why the reconnect mechanism can not detect the situation and use the correct end point to get a new refresh token when the refresh token is expired...

dbu avatar Nov 26 '18 14:11 dbu

This is fixed in the v3 client, at least if you're using client creds or user creds. The underlying go oauth2 libraries support automatic refresh of access tokens using a refresh token. However, it doesn't support refreshing the refresh token once that expires.

This was fixed by re-authenticating and creating a new http client and oauth token source in response to a 401 returned from the API.

sneal avatar Nov 16 '22 05:11 sneal

@sneal, sorry for opening the issue again, but just to make this clear: a client config which has been created via NewFromCFHome should be able to renew access tokens automatically?

ne0h avatar May 09 '23 11:05 ne0h

I'm having this issue on the latest release of the client, my refresher token is expired. But the client does not reauthenticating.

MB175 avatar Aug 15 '23 11:08 MB175