How should we handle token expiration? Not sure if go-cfclient handles this for us.
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?
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.
Hi @srbry, thanks a lot, seems that I totally missed that issue, sorry for that. I will read up there!
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...
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, 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?
I'm having this issue on the latest release of the client, my refresher token is expired. But the client does not reauthenticating.