Skip to content

ProvidedAccessTokenStrategy and AccessTokenHelpers.refreshCachedAccessToken do not properly refresh access token #25

@sspenst

Description

@sspenst

ProvidedAccessTokenStrategy and AccessTokenHelpers.refreshCachedAccessToken do not properly refresh access token

There are multiple problems in the current client on main - this is unreleased, I know, but figured I should still file a issue - when trying to refresh access tokens.

  1. The refresh token endpoint requires the Authorization: Basic base64(client_id:client_secret) header, despite the docs saying it does not.
    ![imag(https://github.com/spotify/spotify-web-api-ts-sdk/assets/2755722/359abab5-fe1d-4a67-a307-eb433c204734)

  2. Because of ☝️, the ProvidedAccessTokenStrategy incorrectly implements refreshTokenAction by means of AccessTokenHelpers.refreshCachedAccessToken

	private static async refreshToken(
		clientId: string,
		refreshToken: string,
	): Promise<AccessToken> {
		const params = new URLSearchParams();
		params.append("client_id", clientId);
		params.append("grant_type", "refresh_token");
		params.append("refresh_token", refreshToken);

		const result = await fetch("https://accounts.spotify.com/api/token", {
			method: "POST",
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
			},
			body: params,
		});

		const text = await result.text();

		if (!result.ok) {
			throw new Error(`Failed to refresh token: ${result.statusText}, ${text}`);
		}

		const json: AccessToken = JSON.parse(text);
		return json;
	}

As you can see, the Authorization header is missing - I've validated that this request does work when provided the header (I've patched it locally and linked it to my project).

The consequence of this, currently, is that you then need to pass the client_secret the whole way through the stack to the AccessTokenHelpers.refreshCachedAccessToken function which is what my patch dos.

This leads to the next issue....

  1. The refreshToken endpoint response type/docs is wrong or has a bug.
  • On the [docs page for refreshing token(https://developer.spotify.com/documentation/web-api/tutorials/refreshing-tokens), the response is noted to be of this type:
{
access_token: 'BQBLuPRYBQ...BP8stIv5xr-Iwaf4l8eg',
token_type: 'Bearer',
expires_in: 3600,
refresh_token: 'AQAQfyEFmJJuCvAFh...cG_m-2KTgNDaDMQqjrOa3',
scope: 'user-read-email user-read-private'
}

This is incorrect as the refresh_token field is no returned - this cause a bug in the ProvidedAccessTokenStrategy as the current code assumes the refresh_token is there.

You can see that when this.refreshToken is called, the accessToken in memory is completely replaced. This then causes the bug to occur next time we attempt to refresh because there is no refresh_token on the access_token

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions