So all of a sudden they decide I need an authorization header for Spotify Search API.
My application runs in C++ using Poco Net libraries and I can't get it to work.
I went through all that process of getting the "code" that I am supposed to exchange for the token. I assume this code is valid, even though I used just a totally unrelated domain then copied it of the variable that was sent to that page.
See https://developer.spotify.com/web-api/authorization-guide/
This is my code that isn't working:
bool getToken()
{
Poco::URI loginURI( "https://accounts.spotify.com" );
Poco::Net::HTTPSClientSession loginSession( loginURI.getHost(), loginURI.getPort(), context );
// Poco::Net::HTTPBasicCredentials credentials( clientId, clientSecret );
std::ostringstream requestOStr;
requestOStr << "https://accounts.spotify.com/api/token?grant_type=authorization_code&code="
<< (m_refreshToken.empty() ? code : m_refreshToken)
<< "&redirect_uri=" << redirectURI
<< "&client_id=" << clientId << "&client_secret=" << clientSecret;
std::string requestStr( requestOStr.str() );
Poco::Net::HTTPRequest loginRequest( Poco::Net::HTTPRequest::HTTP_POST, requestStr,
Poco::Net::HTTPMessage::HTTP_1_1 );
// credentials.authenticate( loginRequest );
loginSession.sendRequest( loginRequest );
Poco::Net::HTTPResponse response;
std::istream& rs = loginSession.receiveResponse( response );
std::cout << "Login request " << requestStr << std::endl;
std::cout << "Login response status " << static_cast<int>(response.getStatus()) << ", "
<< response.getReason() << std::endl;
std::string rsStr(std::istreambuf_iterator<char>(rs), {});
if( rsStr.empty() )
{
std::cout << "No results" << std::endl;
return false;
}
else
{
std::cout << "Logon response:\n" << rsStr << std::endl;
}
Parser parser;
Var result;
result = parser.parse(rsStr);
Object::Ptr obj = result.extract<Object::Ptr>();
try
{
Var tokenVar = obj->get( "access_token ");
if( tokenVar.isString() )
{
m_token = tokenVar.convert< std::string >();
}
else
{
std::cerr << "Could not get access token" << std::endl;
return false;
}
Var refreshTokenVar = obj->get( "refresh_token" );
if( refreshTokenVar.isString() )
{
m_refreshToken = refreshTokenVar.convert< std::string >();
}
return true;
}
catch( const std::exception& err )
{
std::cerr << "Error getting login token" << err.what() << std::endl;
return false;
}
}
I tried the BasicCredentials instead of putting client id and clientSecret into the request but that got the same result.
This is how the HTTP request looks with the values modified:
https://accounts.spotify.com/api/token?grant_type=authorization_code&code=THE_CODE&redirect_uri=THE_REDIRECT_URI&client_id=THE_CLIENT_ID&client_secret=THE_CLIENT_SECRET
The response I am getting is:
Login response status 400, Bad Request
{"error":"server_error","error_description":"Unexpected status: 400"}