【问题标题】:POST with Basic Auth fails on Android but works in C#带有基本身份验证的 POST 在 Android 上失败,但在 C# 中有效
【发布时间】:2011-08-04 18:55:27
【问题描述】:

我正在开发的应用程序需要我将数据发布到第 3 方 API。我从一开始就一直在努力进行身份验证,并且越来越拖延,现在我陷入了困境。

我曾尝试使用Authenticator,但已阅读有关某些 Android 版本中似乎存在错误的所有信息:Authentication Example

我尝试了几种不同的选项,包括Apache Commons HTTP Library,但均未成功。毕竟,我决定确保 API 不是痛点。所以我写了一个快速的WinForms 程序来测试API,它在第一次尝试时运行良好。因此,我使用的想法和使用的 API 看起来都不错,但我迫切需要一些关于 Java 代码为什么不起作用的指导。

示例如下:

每次都能运行的 C# 代码:

        System.Net.ServicePointManager.Expect100Continue = false;
        // Create a request using a URL that can receive a post. 
        WebRequest request = WebRequest.Create(addWorkoutUrl);
        // Set the Method property of the request to POST.
        request.Method = "POST";
        // Create POST data and convert it to a byte array.
        string postData = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        // Set the ContentType property of the WebRequest.
        request.Headers["X-API-KEY"] = apiKey;
        request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("username:password"));
        request.ContentType = "application/x-www-form-urlencoded";
        // Set the ContentLength property of the WebRequest.
        request.ContentLength = byteArray.Length;
        // Get the request stream.
        Stream dataStream = request.GetRequestStream();
        // Write the data to the request stream.
        dataStream.Write(byteArray, 0, byteArray.Length);
        // Close the Stream object.
        dataStream.Close();
        // Get the response.
        WebResponse response = request.GetResponse();
        // Display the status.
        MessageBox.Show(((HttpWebResponse)response).StatusDescription);
        // Get the stream containing content returned by the server.
        dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Display the content.
        MessageBox.Show(responseFromServer);
        // Clean up the streams.
        reader.Close();
        dataStream.Close();
        response.Close();

目前返回 500:Internal Server Error 的 Android 的 Java 代码,但我认为这是我的错。

    URL url;
    String data = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
HttpURLConnection connection = null;
    //Create connection
    url = new URL(urlBasePath);
    connection = (HttpURLConnection)url.openConnection();
    connection.setConnectTimeout(10000);
    connection.setUseCaches(false);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
    connection.setRequestProperty("Accept","*/*");
    connection.setRequestProperty("X-API-KEY", apiKey);
    connection.setRequestProperty("Authorization", "Basic " +
    Base64.encode((username + ":" + password).getBytes("UTF-8"), Base64.DEFAULT));
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + Integer.toString(data.getBytes("UTF-8").length));

    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
    wr.write(data.getBytes("UTF-8"));
    wr.flush();
    wr.close();
    statusCode = connection.getResponseCode();
    statusReason = connection.getResponseMessage();
    //At this point, I have the 500 error...

【问题讨论】:

  • 经过进一步研究,我终于找到了问题所在,尽管我仍然需要有关如何解决它的帮助。似乎 Android 上的 Base64 编码与 C# 大不相同,如果我跳过编码并仅从 C# 复制编码字符串,那么一切正常。有人对我在 Base64 编码中做错了什么有建议吗?

标签: android http-post basic-authentication


【解决方案1】:

在偶然发现上面评论中提到的根本原因后,我终于找到了问题所在。

我在示例中使用了Base64.encode(),但我需要使用Base64.encodeToString()

区别在于 encode() 返回 byte[]encodeToString() 返回 string 我期待。

希望这将帮助其他被此抓住的人。

【讨论】:

    【解决方案2】:

    这是一个更好的 POST 方法。

    install-package HttpClient

    然后:

    public void DoPost()
    {
        var httpClient = new HttpClient();
        var creds = string.Format("{0}:{1}", _username, _password);
        var basicAuth = string.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(creds)));
        httpClient.DefaultRequestHeaders.Add("Authorization", basicAuth);
        var post = httpClient.PostAsync(_url, 
            new FormUrlEncodedContent(new Dictionary<string, string>
                {
                    { "name", "Henrik" },
                    { "age", "99" }
                }));
    
        post.Wait();
    }
    

    【讨论】:

      【解决方案3】:

      我在java中试过这个

      import java.io.*;
      import java.net.*;
      
      class download{   
          public static void main(String args[]){
              try{
                  String details = "API-Key=e6d871be90a689&orderInfo={\"booking\":{\"restaurantinfo\":{\"id\":\"5722\"},\"referrer\":{\"id\": \"9448476530\" },   \"bookingdetails\":{\"instructions\":\"Make the stuff spicy\",\"bookingtime\": \"2011-11-09 12:12 pm\", \"num_guests\": \"5\"}, \"customerinfo\":{\"name\":\"Ramjee Ganti\",    \"mobile\":\"9345245530\",  \"email\": \"sajid@pappilon.in\",   \"landline\":{ \"number\":\"0908998393\",\"ext\":\"456\"}}}}";
      
                  Authenticator.setDefault(new Authenticator() {
                      protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication("admin", "1234".toCharArray());
                      }
                  });
      
                  HttpURLConnection conn = null;
                  //URL url = new URL("http://api-justeat.in/ma/orders/index");
                              URL url = new URL("http://api.geanly.in/ma/order_ma/index");
                  conn = (HttpURLConnection) url.openConnection();
      
                  conn.setDoOutput(true);
                  conn.setDoInput (true);
      
                  conn.setRequestMethod("POST");
                  //conn.setRequestMethod(HttpConnection.POST);
                  DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
                  outStream.writeBytes(details);
                  outStream.flush();
                  outStream.close();          
      
                  //Get Response  
                  InputStream is = conn.getInputStream();
                  BufferedReader rd = new BufferedReader(new InputStreamReader(is));
                  String line;
                  StringBuffer response = new StringBuffer(); 
      
                  while((line = rd.readLine()) != null) {
                       System.out.println(line);
                  }
      
                  rd.close();
                  System.out.println(conn.getResponseCode() + "\n\n");
              }catch(Exception e){
                          System.out.println(e);         
              }
          }
      }
      

      这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2013-01-02
        • 2015-04-06
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多