Передача параметров строки запроса в вызове API OpenPaths.cc с OAuth не работает
Я пытаюсь вызвать API службы отдыха OpenPaths.cc, который требует двухстороннего OAuth. Для этого я использую библиотеку DevDefined.OAuth (я попробовал пакет nuget и последнюю версию из github). Это работает, когда я не передаю параметры в строке запроса, но возвращает 400 NOT AUTHORIZED, когда я передаю параметры.
Рабочий образец без параметров:
public class OpenPathsRequest
{
private const string accessKey = "your personal access key";
private const string secretKey = "your personal secret";
private const string url = "https://openpaths.cc/api/1";
private OAuthSession session;
public OpenPathsRequest()
{
var consumerContext = new OAuthConsumerContext
{
ConsumerKey = accessKey,
ConsumerSecret = secretKey,
SignatureMethod = SignatureMethod.HmacSha1,
UseHeaderForOAuthParameters = true
};
session = new OAuthSession(consumerContext, url, url, url);
}
private string GetWebResponseAsString(HttpWebResponse response)
{
Encoding enc = System.Text.Encoding.GetEncoding(1252);
StreamReader loResponseStream = new StreamReader(response.GetResponseStream(), enc);
return loResponseStream.ReadToEnd();
}
public string GetResponse()
{
HttpWebResponse response = session.Request().Get().ForUrl(url).ToWebResponse();
var result = GetWebResponseAsString(response);
return result;
}
}
class Program
{
static void Main(string[] args)
{
// create new OpenPathsRequest and get result
var request = new OpenPathsRequest();
var response = request.GetResponse();
Console.WriteLine(response);
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
Но когда я изменяю метод GetResponse и передаю 2 параметра (start_time и end_time), примерно так:
public string GetResponse()
{
HttpWebResponse response = session.Request().Get().ForUrl(url).WithQueryParameters(
new { start_time = 1364962612, end_time = 1364991412 }).ToWebResponse();
var result = GetWebResponseAsString(response);
return result;
}
В результате получается следующий HTTP-запрос (ключ потребителя опущен):
GET https://openpaths.cc/api/1?start_time=1364962612&end_time=1364991412 HTTP/1.1
Authorization: OAuth oauth_nonce="7b5da37a-6227-4ded-ae8b-a695e789ef90",oauth_consumer_key="**********",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1365058952",oauth_version="1.0",oauth_signature="tAk4KMj%2FsiG6BTLSmvDNKXbBpNs%3D"
Host: openpaths.cc
Connection: Keep-Alive
Я получаю ответ об ошибке:
HTTP/1.1 400 Bad Request
Date: Thu, 04 Apr 2013 07:03:26 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 19
Server: TornadoServer/2.0
Set-Cookie: _xsrf=bf20487382b64eeb8646d31b0770db85; Path=/
Set-Cookie: session_id=ZTk2Mjk1MzIzNWNiMmRjMTY1ZmY5Y2ExNWUwMGY5ZTAxZmY1NGIyODljZGJiNzRlMmIyMWI4NTA3YzUwYWJlYg==|1365059006|7459a7ff95039279e9686ceb76b58918fd9f3e48; expires=Thu, 04 Apr 2013 07:18:26 GMT; Path=/
400: NOT AUTHORIZED
Вся помощь будет принята с благодарностью. Заранее спасибо.
Harmen
1 ответ
Решено! Очевидно, что OpenPaths.cc API требует подписи БЕЗ дополнительных параметров запроса в базовой строке подписи. Я считаю, что это не соответствует спецификации OAuth, не так ли? В любом случае, с DevDefined.OAuth я могу легко решить эту проблему, вызвав SignWithoutToken перед вызовом WithQueryParameters, например, так:
public string GetResponse()
{
HttpWebResponse response = session.Request().Get().ForUrl(url).
SignWithoutToken().
WithQueryParameters(new { start_time = 1364962612, end_time = 1364991412 }).
ToWebResponse();
var result = GetWebResponseAsString(response);
return result;
}