zmb3 / spotify

A Go wrapper for the Spotify Web API
Apache License 2.0
1.37k stars 287 forks source link

How to refresh access token? #108

Closed Nikos410 closed 4 years ago

Nikos410 commented 4 years ago

Hi there and thanks for this great library, it saved us a lot of work :)

I do have one problem though - an access token expires after 1 hour, but can be refreshed using the refresh token:

Access tokens are deliberately set to expire after a short time, after which new tokens may be granted by supplying the refresh token originally obtained during the authorization code exchange.

(https://developer.spotify.com/documentation/general/guides/authorization-guide#4-requesting-a-refreshed-access-token-spotify-returns-a-new-access-token-to-your-app)

Is there a way to do this using this library?

Thanks in advance!

zmb3 commented 4 years ago

See also #7. If you're using the authorization code flow, the library should refresh the token for you automatically.

If you're using the client credentials flow folks have just been recreating the client. Definitely open to ideas for making that workflow easier.

chew-z commented 4 years ago

As per this discussion newToken, err := src.Token() // this actually goes and renews the tokens which implies, I think, that zmb3/spotify/auth.go client.Token() should also refresh token.

Now, this is just sidenote but you rarely need spotify token to last beyond default 60 minutes.

  1. If you store spotify cookies you would be re-authorized transparently in the background
  2. oauth2 token had been designed to be stateful not stateless (hence variable called state). Many people for simplicity code per app token (like const state=abc123) but it is not as intended.
Nikos410 commented 4 years ago

Hi, sorry for taking a while to respond.

I think I'm using the authorization code flow, like in the example in README.md.

So that means, if I create a client with Authenticator.NewClient(token) and then perform actions using that client, the token will be updated automatically?

chew-z commented 4 years ago

Yes. Your client should be authorized even if more then an hour passed.

Do log.Println(token.Expiry.Sub(time.Now())) to make sure. And newToken, _ := client.Token() to obtain new token implicit.

If you would like to store new token (to file or database) this pseudocode might help.

        tok, err := getTokenFromDB()
        if err == nil {
            client := auth.NewClient(tok)

                if m, _ := time.ParseDuration("5m30s"); time.Until(tok.Expiry) < m {
                    newToken, _ := client.Token()
                    updateTokenInDB(newToken)
                }
            return &client
        }
Nikos410 commented 4 years ago

Alright, thank you very much, that does help me a lot