Я пытаюсь создать инструмент для общения с API Assembla, и у меня возникли проблемы с правильной аутентификацией. Я использую процедуру с тремя шагами, как описано здесь. Получение PIN-кода теперь не проблема, хотя я хочу сделать его более интеллектуальным в будущем. У меня возникли проблемы с обменом PIN-кодом на токен-носитель.
Мой код такой:
private void button1_Click(object sender, EventArgs e)
{
var url = string.Format("https://api.assembla.com/token");
var web = (HttpWebRequest)WebRequest.Create(url);
web.Method = "POST";
//web.Accept = "application/x-www-form-urlencoded";
web.ContentType = "application/x-www-form-urlencoded";
web.Headers["client_id"] = "xxxxx";
web.Headers["client_secret"] = "xxxxxx";
var data = string.Format("grant_type=pin_code&pin_code={0}", textBox1.Text);
byte[] buffer = Encoding.UTF8.GetBytes(data);
web.ContentLength = buffer.Length;
var postData = web.GetRequestStream();
postData.Write(buffer, 0, buffer.Length);
postData.Close();
WebResponse resp = web.GetResponse();
var sr = new StreamReader(resp.GetResponseStream());
var result = sr.ReadToEnd().Trim();
}
Это приводит к исключению webrequest: The remote server returns an error: (400) Bad Request.
Ошибка WebResponse resp = web.GetResponse();
на строку WebResponse resp = web.GetResponse();
Я не уверен, как получить дополнительную информацию об ошибке. Однако, если я использую http://requestmaker.com/ для заполнения моих учетных данных и пин-кода, он возвращает тот же код ошибки, а также тело ответа, говорящее {"error":"invalid_request","error_description":"'client_id' required."}
. Я попробовал requestmaker как с client_id как заголовки, так и с жестким кодом, как в примере Assembla " https://_client_id:[email protected]/token?grant_type=pin_code&pin_code=_pin_code
". Оба возвращают тот же результат.
Это первый раз, когда я делал что-либо с запросом http, так что это может быть какой-то глупый обзор с моей стороны. Ошибка, вероятно, специфична для Assembla, но если кто-то увидит какие-либо очевидные ошибки в моем коде, я был бы благодарен за корректирующие рекомендации.
В этом ответе есть более или менее полный API для обмена PIN-кодом для токенов доступа. Этот API предназначен для получения токенов загрузки учетной записи imgUr через OAuth. Часть соответствующей функции:
// the PIN previously received
string myPin = "";
private bool RequestToken(string CliId, string CliSecret)
{
// request format as per imgUR API - YMMV
string sReq = string.Format("client_id={0}&client_secret={1}&grant_type=pin&pin={2}",
CliId, CliSecret, myPin);
string url = "https://api.imgur.com/oauth2/token/";
bool myResult = true;
// create request for the URL, using POST method
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
// convert the request, set content format, length
byte[] data = System.Text.Encoding.UTF8.GetBytes(sReq);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
// write the date to request stream
Stream dstream = request.GetRequestStream();
dstream.Write(data, 0, data.Length);
dstream.Close();
// ToDo:
// GetResponse() in Try/Catch
// if there is an exception get the exact error
// otherwise:
// read the stream and parse (json) the result to get access token
return myResult;
}
Существует не так много отличий от того, что у вас есть, но все они связаны с форматированием запроса и его отправкой. По крайней мере, для imgUr документы очень специфичны в отношении того, как должна выглядеть строка запроса, поэтому дважды проверьте это на документы для любого сайта, к которому вы пытаетесь получить доступ.
Обратите внимание, что в большинстве случаев результатом является json, который нужно будет анализировать, чтобы получить токены.