连接到shutterstock api的Android应用程序抛出错误401

时间:2016-05-31 18:44:38

标签: java android authentication https

我正在尝试将我的Android应用程序连接到shutterstock api,以便它可以在那里搜索一些图像。它使用https方案+基本身份验证标头允许用户进行所有搜索请求。我使用HttpsURLConnection在常规Java项目中实现了该功能,并且能够获得正确的JSON响应。 java代码如下所示:

HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();//proxy);
        String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164";
        String encoded = Base64.getEncoder().encodeToString((username+":"+password).getBytes("UTF-8"));
        System.out.println(encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==")); // prints true

        urlConnection.setRequestProperty("Authorization", "Basic "+encoded);

当将其移植到Android中时,它抛出了一个带有401错误代码的IOException。正如SO上的许多帖子(如here中所述)所解释的那样,我使用额外的try-catch相应地修改了代码,如下所示:

String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164", encoded = "";
            encoded = Base64.encodeToString((username+":"+password).getBytes("UTF-8"), Base64.URL_SAFE);
            Log.e("test", "encoded strings match:" + encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==") + "\n" + encoded); // prints false but string is same!!

            URL url = new URL(reqUrl);
            connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestProperty("Authorization", "Basic "+encoded);

try {
    if (connection != null) {
        connection.connect();

        if (200 == connection.getResponseCode()) { // ---> throws IOException
            BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
            String output;
            while ((output = br.readLine()) != null) {
                Log.e("test", output);
                response.append(output);
            }
            connection.disconnect();
            return response.toString();
        }
    }
} catch (IOException e) {
    try {
        Log.e("test", e.getMessage()); // ---> prints "No authentication challenges found"
        Log.e("test", connection.getResponseCode() + ":" + connection.getResponseMessage() + connection.getHeaderFields());
        //---> prints 401:Unauthorized{null=[HTTP/1.1 401 Unauthorized], cache-control=[no-cache], Connection=[keep-alive], Content-Length=[38], Content-Type=[application/json; charset=utf8], Date=[Tue, 31 May 2016 14:11:28 GMT], Server=[nginx], X-Android-Received-Millis=[1464703888222], X-Android-Sent-Millis=[1464703887592], x-end-user-request-id=[f754ec7f-c344-431b-b641-360aabb70184], x-shutterstock-app-version=[apitwo-625], x-shutterstock-resource=[/v2/images/search]}

        if (401 == connection.getResponseCode()) {
            InputStream es = connection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(es));
            String output;
            while ((output = br.readLine()) != null) {
                Log.e("test", output); // ---> prints {"message":"Invalid auth credentials"}
                response.append(output);
            }
            connection.disconnect();
            return response.toString();
        } else {
            Log.e("test","Could not connect! " + connection.getResponseCode() + ":" + connection.getResponseMessage() + ". " + connection.getRequestMethod());
        }
    }catch (Exception e1){e1.printStackTrace();}
}

我无法检查Firefox的Rest客户端中的响应标头,因为当我添加Authentication标头时它不会将请求发送到服务器。

所以这里的问题是:

  1. 这是处理Android中401错误的正确方法吗?我会在内部的try-catch中获得JSON响应吗?
  2. java程序使用与Android中完全相同的编码字符串。为什么String.equals()返回" true"在java中但是" false"在android?
  3. 来自服务器的错误消息显示"无效的身份验证凭据"。由于任何原因,编码字符串在Android和Java之间是否不同?如果是,那么第2点是有道理的。

1 个答案:

答案 0 :(得分:0)

我将java程序中的编码字符串复制到Android变量中,并且能够使用shutterstock成功验证。事实上,Android和Java上的编码字符串虽然采用UTF-8格式,但却有所不同。这也解释了Android中的“false”和来自服务器的“Invalid credentials”消息。

当人眼的编码字符串相同时,只是不确定为什么/它如何不同!