I am trying to obtain an access token from Spotify using the Authorization Code Flow with scopes, but I'm encountering an issue where the token request does not seem to work properly. I am able to successfully request the authorization code, but when I try to exchange it for an access token with the scopes, I get a 401 Bad Request error with the message "Response status code does not indicate success: 401 (Bad Request)." I dont know what am i doing wrong tbh.
I am able to get the token correctly but it doesnt work for this endpoint (Requires this scopes user-read-private user-read-email)
Example of curl by spotify : curl --request GET \
--url \
--header 'Authorization: Bearer 1POdFZRZbvb...qqillRxMr2z'
My logic :
public async Task<SpotifyTokenResponseEntity> GetSpotifyAccessTokenScopes(SpotifyAuthRequestEntity spotifyAuthRequestEntity, string[] scopes)
{
var scopeString = string.Join(" ", scopes);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("scope", scopeString)
});
var authenticationString = $"{spotifyAuthRequestEntity.ClientId}:{spotifyAuthRequestEntity.ClientSecret}";
var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString));
var request = new HttpRequestMessage(HttpMethod.Post, _tokenUrl)
{
Headers = { Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString) },
Content = content
};
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var errorMessage = await response.Content.ReadAsStringAsync();
throw new Exception($"Response status code does not indicate success: {response.StatusCode} ({errorMessage})");
}
var jsonResponse = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<SpotifyTokenResponseEntity>(jsonResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
And my command handler :
public class GetSpotifyAuthTokenScopes : IRequest<ResponseObjectJsonDto>
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
public class GetSpotifyAuthTokenScopesHandler : IRequestHandler<GetSpotifyAuthTokenScopes, ResponseObjectJsonDto>
{
private readonly ISpotifyAuthService _spotifyAuthService;
public GetSpotifyAuthTokenScopesHandler(ISpotifyAuthService spotifyAuthService)
{
_spotifyAuthService = spotifyAuthService;
}
public async Task<ResponseObjectJsonDto> Handle(GetSpotifyAuthTokenScopes request, CancellationToken cancellationToken)
{
try
{
var spotifyAuthRequest = new SpotifyAuthRequestEntity
{
ClientId = request.ClientId,
ClientSecret = request.ClientSecret
};
var scopes = new[]
{
"user-read-private",
"user-read-email"
};
Console.WriteLine($"Requesting token with scopes: {string.Join(", ", scopes)}");
var token = await _spotifyAuthService.GetSpotifyAccessTokenScopes(spotifyAuthRequest, scopes);
return new ResponseObjectJsonDto()
{
Code = (int)CodeHttp.OK,
Message = "Token generado correctamente.",
Response = token
};
}
catch (Exception ex)
{
return new ResponseObjectJsonDto()
{
Code = (int)CodeHttp.INTERNALSERVER,
Message = ex.Message,
Response = null
};
}
}
}
I am trying to obtain an access token from Spotify using the Authorization Code Flow with scopes, but I'm encountering an issue where the token request does not seem to work properly. I am able to successfully request the authorization code, but when I try to exchange it for an access token with the scopes, I get a 401 Bad Request error with the message "Response status code does not indicate success: 401 (Bad Request)." I dont know what am i doing wrong tbh.
I am able to get the token correctly but it doesnt work for this endpoint https://api.spotify.com/v1/me (Requires this scopes user-read-private user-read-email)
Example of curl by spotify : curl --request GET \
--url https://api.spotify.com/v1/me \
--header 'Authorization: Bearer 1POdFZRZbvb...qqillRxMr2z'
My logic :
public async Task<SpotifyTokenResponseEntity> GetSpotifyAccessTokenScopes(SpotifyAuthRequestEntity spotifyAuthRequestEntity, string[] scopes)
{
var scopeString = string.Join(" ", scopes);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("scope", scopeString)
});
var authenticationString = $"{spotifyAuthRequestEntity.ClientId}:{spotifyAuthRequestEntity.ClientSecret}";
var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString));
var request = new HttpRequestMessage(HttpMethod.Post, _tokenUrl)
{
Headers = { Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString) },
Content = content
};
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var errorMessage = await response.Content.ReadAsStringAsync();
throw new Exception($"Response status code does not indicate success: {response.StatusCode} ({errorMessage})");
}
var jsonResponse = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<SpotifyTokenResponseEntity>(jsonResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
And my command handler :
public class GetSpotifyAuthTokenScopes : IRequest<ResponseObjectJsonDto>
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
public class GetSpotifyAuthTokenScopesHandler : IRequestHandler<GetSpotifyAuthTokenScopes, ResponseObjectJsonDto>
{
private readonly ISpotifyAuthService _spotifyAuthService;
public GetSpotifyAuthTokenScopesHandler(ISpotifyAuthService spotifyAuthService)
{
_spotifyAuthService = spotifyAuthService;
}
public async Task<ResponseObjectJsonDto> Handle(GetSpotifyAuthTokenScopes request, CancellationToken cancellationToken)
{
try
{
var spotifyAuthRequest = new SpotifyAuthRequestEntity
{
ClientId = request.ClientId,
ClientSecret = request.ClientSecret
};
var scopes = new[]
{
"user-read-private",
"user-read-email"
};
Console.WriteLine($"Requesting token with scopes: {string.Join(", ", scopes)}");
var token = await _spotifyAuthService.GetSpotifyAccessTokenScopes(spotifyAuthRequest, scopes);
return new ResponseObjectJsonDto()
{
Code = (int)CodeHttp.OK,
Message = "Token generado correctamente.",
Response = token
};
}
catch (Exception ex)
{
return new ResponseObjectJsonDto()
{
Code = (int)CodeHttp.INTERNALSERVER,
Message = ex.Message,
Response = null
};
}
}
}
You are setting the Authorization header value as Basic
. Not Bearer
.
Should be
var request = new HttpRequestMessage(HttpMethod.Post, _tokenUrl)
{
Headers = { Authorization = new AuthenticationHeaderValue("Bearer", base64EncodedAuthenticationString) },
Content = content
};
Basic
. NotBearer
. Should beAuthorization = new AuthenticationHeaderValue("Bearer", base64EncodedAuthenticationString)
– Sani Huttunen Commented Jan 15 at 4:54