Search code examples
jakarta-eeutf-8instagramurlencodeinstagram-api

Instagram API error 500 UTF-8 hashtags with enforced signature


I am receiving 500 error from a simple instagram GET request. My code works when the hashtag contains normal ascii characters, or when my app has the checkbox "Enforce signed requests" unchecked. But I cannot get anything to work when I try with a utf8 hashtag and signed requests enforced. I saw that signed requests will be mandatory soon, so I need it to work. I want to get all images for a tag like #über.

public static String signRequest(String key, String data) throws Exception {
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
    sha256_HMAC.init(secret_key);
    return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

public static void getLatestImagesForHashtag(String hashtag, String client_id, String secret) throws Exception {
    String endpoint = "/tags/" + URLEncoder.encode(hashtag, "UTF-8") + "/media/recent";
    String request_data = endpoint + "|client_id=" + client_id;
    System.out.println("SIGNING DATA: " + request_data);
    String signature = InstagramUtil.signRequest(secret, request_data);
    System.out.println("SIG VAL: " + signature);
    String url = "https://api.instagram.com/v1" + endpoint + "?client_id=" + client_id + "&sig=" + signature;
    URL obj;
    try {
        obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        //Blah blah blah

And the response I get

Info:   SIGNING DATA: /tags/%C3%BCber/media/recent|client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Info:   SIG VAL: 503fd3fb7072eea8284576940b3fe75125a5bbbd9f505f22507776cbb6760d5d
Info:   Sending 'GET' request to URL : https://api.instagram.com/v1/tags/%C3%BCber/media/recent?client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&sig=503fd3fb7072eea8284576940b3fe75125a5bbbd9f505f22507776cbb6760d5d
Info:   Response Code : 500
Info:   Response Msg : INTERNAL SERVER ERROR

The data response is: Oops, an error occurred.

I have tried many different combinations of encoding the hashtag in the endpoint and in the signature data. It is odd that I receive a 500 error and not a 403 if it is a signature problem. Am I doing something wrong with encoding?


Solution

  • I think this issue is apparently a bug of Instagram API.
    I tested various request patterns.

    "Enforce signed requests" is enabled

    /v1/tags/search?access_token=<access token>&q=%e3%81%82&sig=<correct sig>
    

    -> 500 (expected 200)

    /v1/tags/search?access_token=<access token>&q=%e3%81%82&sig=<incorrect sig>
    

    -> 500 (expected 403)

    /v1/tags/search?access_token=<access token>&q=%e3%81%82
    

    -> 403 (as expected)

    /v1/tags/search?access_token=<access token>&q=abc&sig=<correct sig>
    

    -> 200 (as expected)

    "Enforce signed requests" is disabled

    /v1/tags/search?access_token=<access token>&q=%e3%81%82&sig=<correct sig>
    

    -> 200 (as expected)

    /v1/tags/search?access_token=<access token>&q=%e3%81%82&sig=<incorrect sig>
    

    -> 403 (as expected)

    When "Enforce signed requests" is enabled, a request which has non-ascii utf-8 characters in its uri always get 500. If turn off it, everything work fine. This is apparently not an issue caused by incorrect sig parameter or wrong encoding.
    I already reported this issue to Instagram via bugtool 10 days ago. No reaction from them so far.
    (Sorry to answer again. My 1st answer was deleted.)

    [UPDATE 5 Sep.]
    At last, this issue seems to be fixed.
    My IG app works fine with Enforce Signed Requests setting now.
    Note: If an endpoint uri has url-encoded characters (such as /tags/%E3%81%82/media/recent), you need to generate sig parameter from decoded endpoint string.