zmb3 / spotify

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

v2: Not able to find the OAuth Token in Client #168

Closed elivlo closed 2 years ago

elivlo commented 2 years ago

Hi :smiley:,

I just pulled the new version (v2). Because my application was running as a daemon I saved the access_token and refresh_token in case my program is failing. In v1 I got the token by calling client.Token().

But sadly this is no longer possible in v2.

So my question is how am I should do that now?

best regards

elivlo commented 2 years ago

Basically I miss these two functions from v1 in v2:

// NewClient creates a Client that will use the specified access token for its API requests.
func (a Authenticator) NewClient(token *oauth2.Token) Client {
    client := a.config.Client(a.context, token)
    return Client{
        http:    client,
        baseURL: baseAddress,
    }
}

// Token gets the client's current token.
func (c *Client) Token() (*oauth2.Token, error) {
    transport, ok := c.http.Transport.(*oauth2.Transport)
    if !ok {
        return nil, errors.New("spotify: oauth2 transport type not correct")
    }
    t, err := transport.Source.Token()
    if err != nil {
        return nil, err
    }

    return t, nil
}
strideynet commented 2 years ago

Hey!

You should be able to call spotify.New(auth.Client(context.Background(), tok)), where tok is the token ? Unless I'm misunderstanding your use-case.

strideynet commented 2 years ago

For what it's worth, it appears Spotify refresh tokens essentially live forever until the user takes some action to revoke your applications access. So for your case of persisting the token, I would save it after you've completed the flow, and then load it in whenever you need it in future.

auth := spotifyauth.New(
spotifyauth.WithRedirectURL("http://localhost:8080/v1/spotify/auth/callback"),
spotifyauth.WithScopes(
    spotifyauth.ScopeUserReadPrivate,
    spotifyauth.ScopeUserReadPlaybackState,
    spotifyauth.ScopeUserReadCurrentlyPlaying,
    spotifyauth.ScopeUserReadRecentlyPlayed,
    ),
)

// In your oauth2 callback handler
tok, err := auth.Token(ctx, state, request)
if err != nil {
  return err
}
saveToken(tok) // wherever you save your token, you need to persist the AccessToken, RefreshToken and Expiry and TokenType fields.

// when your application wants to use an existing token
tok := loadToken(userId) // pull the token from your DB/File

client := spotify.New(auth.Client(context.Background(), tok))
strideynet commented 2 years ago

If you have further questions, please feel free to reach out to me on the Gophers slack (https://invite.slack.golangbridge.org/). I'm @Noah Stride on there :)

elivlo commented 2 years ago

Thank you for the quick reply! Now I understand the workflow of v2, but I think your suggestion in #169 is a good idea.

strideynet commented 2 years ago

Thanks, I'll go ahead and close this but feel free to open/reopen if you have any other issues!