所以突然他们决定我需要一个Spotify Search API的授权标题。
我的应用程序使用Poco Net库在C ++中运行,但我无法使用它。
我完成了获取"代码"的所有过程。我应该交换令牌。我假设这段代码是有效的,即使我只使用了一个完全不相关的域,然后复制了发送到该页面的变量。
请参阅https://developer.spotify.com/web-api/authorization-guide/
这是我的代码:
%s
我尝试使用BasicCredentials而不是将客户端ID和clientSecret放入请求中,但结果相同。
这是HTTP请求在修改后的值中的显示方式:
Thread Name: Thread Group 1-1
Sample Start: 2017-06-02 12:20:45 EDT
Load time: 21015
Connect Time: 0
Latency: 0
Size in bytes: 0
Sent bytes:0
Headers size in bytes: 0
Body size in bytes: 0
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""):
Response code: 500
Response message: javax.mail.MessagingException: Connect failed;
nested exception is:
java.net.ConnectException: Connection timed out: connect
pop3s://enwarali@gmail.com@pop.googlemail.com:995/INBOX[1]
Response headers:
SampleResult fields:
ContentType:
DataEncoding: null
我得到的回应是:
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;
}
}
答案 0 :(得分:0)
好的,我现在回答了我自己的问题。我的错误是误用了POST。
一旦我拥有原始的authorization_code,这就有效。一旦&#34;交换&#34;代码将不再有效。但那是一个不同的问题。
bool getToken()
{
Poco::URI loginURI( "https://accounts.spotify.com" );
Poco::Net::HTTPSClientSession loginSession( loginURI.getHost(), loginURI.getPort(), context );
Poco::Net::HTTPBasicCredentials credentials( clientId, clientSecret );
loginSession.setKeepAlive( true );
std::string requestStr( "https://accounts.spotify.com/api/token" );
Poco::Net::HTTPRequest loginRequest( Poco::Net::HTTPRequest::HTTP_POST,
requestStr,
Poco::Net::HTTPMessage::HTTP_1_1 );
loginRequest.setContentType("application/x-www-form-urlencoded");
loginRequest.setKeepAlive( true );
std::string grantType;
std::string authCode;
if( m_refreshToken.empty() )
{
grantType = "authorization_code";
authCode = code;
}
else
{
grantType = "refresh_token";
authCode = m_refreshToken;
}
std::ostringstream contentOStr;
contentOStr << "grant_type=" << grantType <<
"&code=" << authCode
<< "&redirect_uri=" << redirectURI;
std::string contentStr = contentOStr.str();
loginRequest.setContentLength( contentStr.size() );
credentials.authenticate( loginRequest );
std::ostream& requestOStr = loginSession.sendRequest( loginRequest );
requestOStr << contentStr;
requestOStr.flush();
Poco::Net::HTTPResponse response;
std::istream& rs = loginSession.receiveResponse( response );
std::cout << "Login request ";
loginRequest.write(std::cout);
std::cout << 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;
}
}