Исключение несанкционированного доступа при использовании Yahoo Weather API

Я сделал код для доступа к API погоды Yahoo с присягой, выполнив все шаги, предоставленные Yahoo в документации, как 1) Создать учетную запись Yahoo 2) Создать приложение 3) Приложение белого списка 4) Код С# для доступа к API погоды Yahoo с присягой

Я получаю исключение несанкционированного доступа при запросе API. Вот код:

public class WeatherYdn
{
    public static void Main(string[] args)
    {
        const string appId = "YOUR-WHITELISTED-APPID";
        const string consumerKey = "YOUR-CONSUMER-KEY";
        const string consumerSecret = "YOUR-SECRET-KEY";
        const string url = "https://weather-ydn-yql.media.yahoo.com/forecastrss";

        string timestamp = StringHelper.GenerateTimeStamp();
        String oauthNonce = StringHelper.GenerateNonce();
        IList<string> parameters = new List<string>();
        parameters.Add("oauth_consumer_key=" + consumerKey);
        parameters.Add("oauth_nonce=" + oauthNonce);
        parameters.Add("oauth_signature_method=HMAC-SHA1");
        parameters.Add("oauth_timestamp=" + timestamp);
        parameters.Add("oauth_version=1.0");
        // Make sure value is encoded
            parameters.Add("location=" + HttpUtility.UrlEncode("pune,in", Encoding.UTF8));
            parameters.Add("format=json");
            ((List<string>) parameters).Sort();

            StringBuilder parametersList = new StringBuilder();
            for (int i = 0; i < parameters.Count; i++)
            {
                parametersList.Append(((i > 0) ? "&" : "") + parameters.ElementAt(i));
            }

            var signatureString = "GET&" +
                                  HttpUtility.UrlEncode(url,Encoding.UTF8) + "&" +
                                  HttpUtility.UrlEncode(parametersList.ToString(), Encoding.UTF8);
            string signature = null;
            try
            {
                string secretAccessKey = consumerSecret;
                byte[] secretKey = Encoding.UTF8.GetBytes(secretAccessKey);
                HMACSHA1 hmac = new HMACSHA1(secretKey);
                hmac.Initialize();
                byte[] bytes = Encoding.UTF8.GetBytes(signatureString);
                byte[] rawHmac = hmac.ComputeHash(bytes);
                signature = Convert.ToBase64String(rawHmac);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unable to append signature");                
            }
            string authorizationLine = "OAuth " +
                                       "oauth_consumer_key=\"" + consumerKey + "\", " +
                                       "oauth_nonce=\"" + oauthNonce + "\", " +
                                       "oauth_timestamp=\"" + timestamp + "\", " +
                                       "oauth_signature_method=\"HMAC-SHA1\", " +
                                       "oauth_signature=\"" + signature + "\", " +
                                       "oauth_version=\"1.0\"";

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url + "?location=pune,in&format=json");
            request.Headers.Add("Authorization", authorizationLine);
            request.Headers.Add("Yahoo-App-Id", appId);
            request.ContentType = "application/json; charset=UTF-8";
            request.Accept = "application/json";
            HttpWebResponse response = (HttpWebResponse) request.GetResponse();
            Stream receiveStream = response.GetResponseStream();
            StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
            Console.WriteLine(readStream.ReadLine());
        }    
}

person Tejashri Sawashe    schedule 17.01.2019    source источник
comment
Почему вы обновляете HttpClient и ничего с ним не делаете?   -  person mjwills    schedule 17.01.2019
comment
Возможный дубликат Как сделать HTTP-запрос на получение с параметрами   -  person mjwills    schedule 17.01.2019
comment
У меня похожая проблема. Как исправление?   -  person stuckedoverflow    schedule 20.01.2019


Ответы (4)


В какой строке вы получаете ошибку? GetResponse() возвращает его? Я думаю, что используемые вами учетные данные (appId,consumerKey,consumerSecret) недействительны!

person Dr. K    schedule 17.01.2019
comment
Я проверил все учетные данные, а также связался с технической командой Yahoo, согласно их предложениям, я внес все изменения. Но моя проблема также не была решена. Поэтому я попросил помощи здесь. - person Tejashri Sawashe; 18.01.2019
comment
@TejashriSawashe У меня тоже похожая проблема? Как исправление? - person stuckedoverflow; 20.01.2019
comment
Я получаю тот же ответ - 401 Unauthorized. Преобразованный код из Java в VB.NET очень похож на ваш. Удачи найти решение? - person DonnieDarko; 22.01.2019
comment
я думаю, что вы должны использовать другую библиотеку или другой язык для этого API погоды Yahoo. developer.yahoo.com/weather/ - person Dr. K; 23.01.2019

Для новой аутентификации Yahoo Weather вы можете использовать эту библиотеку Python yahoo-weather.

person Mojtaba Ahadi    schedule 20.01.2019

Я думаю, что ваш код в порядке. Проблема заключается в плохо реализованном декодировании URL на стороне Yahoo. Java URL Encode кодирует в верхнем регистре, а .net HTTPUtility.URLEncode кодирует в нижнем регистре. Я создал метод расширения для строки, который устранит проблему, и URL Encode таким образом, чтобы его мог обрабатывать API Yahoo. После этого все заработало хорошо (у меня была точно такая же проблема, как и у вас).

  <Extension>
    Public Function UppercaseURLEncode(ByVal sourceString As String) As String

        Dim temp As Char() = HttpUtility.UrlEncode(sourceString).ToCharArray()

        For i As Integer = 0 To temp.Length - 2

            If temp(i).ToString().Equals("%", StringComparison.OrdinalIgnoreCase) Then

                temp(i + 1) = Char.ToUpper(temp(i + 1))
                temp(i + 2) = Char.ToUpper(temp(i + 2))

            End If

        Next

        Return New String(temp)

    End Function
person DonnieDarko    schedule 23.01.2019
comment
Вам также необходимо добавить амперсанд к вашему потребительскому ключу в этой строке: string secretAccessKey = ConsumerSecret; Таким образом, это должна быть строка secretAccessKey = ConsumerSecret + &; - person DonnieDarko; 23.01.2019

person    schedule
comment
Пожалуйста, предоставьте объяснение вместе с ответом :) - person GKE; 26.01.2019