Подпись OAuth 1.0 для нового API погоды Yahoo - PullRequest
0 голосов
/ 20 февраля 2019

У меня проблема с генерацией подписи для нового API погоды Yahoo.Они обновили свой API и теперь требовали подписи OAuth 1.0.

Я пытался использовать пример кода из этой документации https://developer.yahoo.com/weather/documentation.html?guccounter=1#oauth-java

Я использую Retrofit 2 и OkHttpClient.Мой код:

public interface WeatherApi {

@Headers({
        "Content-Type: application/json",
        "Yahoo-App-Id: " + YAHOO_APP_ID
})
@GET("forecastrss")
Observable<WeatherInfo> getWeather(@Header("Authorization") String authorization,
                                   @QueryMap Map<String, String> params);

}

public final class WeatherInjection {

public static WeatherApi provideYahooWeatherApi() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient okHttpClient = new OkHttpClient()
            .newBuilder()
            .addInterceptor(interceptor)
            .build();

    Gson gson = new GsonBuilder()
            .registerTypeAdapter(WeatherInfo.class, new WeatherInfo.WeatherInfoJsonDeserializer())
            .create();
    GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(gson);
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(WeatherApi.BASE_URL)
            .client(okHttpClient)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(gsonConverterFactory)
            .build();

    return retrofit.create(WeatherApi.class);
}

}

Сгенерированная здесь подпись:

public String buildAuthorization(String location) {
        try {
            String oauthNonce = UUID.randomUUID().toString();

            long timestamp = System.currentTimeMillis() / 1000;

            List<String> parameters = new ArrayList<>();
            parameters.add("oauth_consumer_key=" + CLIENT_ID);
            parameters.add("oauth_nonce=" + oauthNonce);
            parameters.add("oauth_signature_method=HMAC-SHA1");
            parameters.add("oauth_timestamp=" + timestamp);
            parameters.add("oauth_version=1.0");

            parameters.add("location=" + location);
            parameters.add("format=json");
            Collections.sort(parameters);
            Log.d("My", "Sorted list: " + parameters);

            StringBuilder parametersList = new StringBuilder();
            for (int i = 0; i < parameters.size(); i++) {
                parametersList.append((i > 0) ? "&" : "").append(parameters.get(i));
            }
            Log.d("My", "Parameter list: " + parametersList.toString());

            String signatureString = "GET&" +
                    URLEncoder.encode(BASE_URL + "forecastrss", UTF_8) + "&" +
                    URLEncoder.encode(parametersList.toString(), UTF_8);
            Log.d("My", "Signature: " + signatureString);

            SecretKeySpec signingKey = new SecretKeySpec((CLIENT_SECRET + "&").getBytes(), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            byte[] rawHMAC = mac.doFinal(signatureString.getBytes());
            String signature = Base64.encodeToString(rawHMAC, Base64.NO_WRAP);


            return "OAuth " +
                    "oauth_consumer_key=\"" + CLIENT_ID + "\", " +
                    "oauth_nonce=\"" + oauthNonce + "\", " +
                    "oauth_timestamp=\"" + timestamp + "\", " +
                    "oauth_signature_method=\"HMAC-SHA1\", " +
                    "oauth_signature=\"" + signature + "\", " +
                    "oauth_version=\"1.0\"";
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

Я обнаружил, что когда я использовал какзначение для параметра "location" одним словом (например, "sunnyvale") работает хорошо.Но когда "location" содержит> 1 слова или содержит "," и "", тогда я получаю ошибку 401.Например, «location = sunnyvale, ca» или «Santa Monica» не будут работать, но «SantaMonica» будет работать нормально.

Обращаюсь к вам за помощью

...