Spotify API get user saved tracks error 401 missing token

Viewed 420

I'm building a discord bot with discord.py and I'm trying to get the spotify user saved tracks. This is my auth def:

    @classmethod
    def get_token(self):
        CLIENT_ID = 'myclientid'
        CLIENT_SECRET = "myclientsecret"
        SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
        client_token = base64.b64encode("{}:{}".format(CLIENT_ID, CLIENT_SECRET).encode('UTF-8')).decode('ascii')
        headers = {"Authorization": "Basic {}".format(client_token)}
        payload = {"grant_type": "client_credentials"}
        token_request = requests.post(SPOTIFY_TOKEN_URL, data=payload, headers=headers)
        access_token = json.loads(token_request.text)["access_token"]
        return access_token

This is my def where I try to get the user saved tracks:

@commands.command(name='splayfav', aliases=['splayfavorites', 'splaysavedtracks'], description="Command to see the info from spotify \n __Example:__ \u200b \u200b *!infos*")
async def play_saved_tracks_from_spotify(self, ctx):
    token = self.get_token(ctx)
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {token}',
    }

    response = requests.get('https://api.spotify.com/v1/me/tracks', headers=headers)
    print(response.text)

I get this error:

{
  "error" : {
    "status" : 401,
    "message" : "Missing token"
  }
}

But If I go in the Spotify API console and get manually a token and put it manually after bearer, then it works, obviously I'm trying to automate the process so I can't take it by hand every time. If I print the token it's actually a token(I mean it's not None or similar), but it's like if It is the wrong one. How can I fix this problem?

1 Answers

This error message is stupid. What it should tell you is that your authorization token does not have the grant to access the user.

There's 2 different ways to authorize:

  1. client credentials (as you do, can't access any user related stuff)
  2. Authorization Code Flow, see: https://developer.spotify.com/documentation/general/guides/authorization/code-flow/

The second way requires a bit more setup in your app. Basically get redirected to spotify webpage, then the user selects allow for the required permissions, then you get back a code and with that you can get a token and the refresh token (this one is the interesting part).

Now this is quite a hustle to get through, but once you have the refresh token you can basically do almost the same call you do just to get a refreshed access token. (See "Request a refreshed Access Token" at the bottom of the page I linked above)

So with refresh token you can do:

POST https://accounts.spotify.com/api/token

HEADER:
Authorization: Basic $base64(clientId:clientSecret)

BODY Parameters (form url encoded)
grant_type: refresh_token
refresh_token: <your value here>

Use this improved access token and it will work.

Related