在Android上授权的HTTP POST请求

时间:2022-08-22 19:39:22

When I set "Authorization" header with setHeader from HttpPost then hostname disappears from request and there is always error 400 (bad request) returned. Same code is working fine on pure java (without android) and when I remove setting "Authorization" header also on android it works fine, but I need authorization. This is a code (domain changed):

当我从HttpPost使用setHeader设置“Authorization”标头时,主机名从请求中消失,并且始终返回错误400(错误请求)。相同的代码在纯java(没有android)上正常工作,当我在android上删除设置“Authorization”标题时,它工作正常,但我需要授权。这是一个代码(域已更改):

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://myhost.com/test.php");
post.setHeader("Accept", "application/json");
post.setHeader("User-Agent", "Apache-HttpClient/4.1 (java 1.5)");
post.setHeader("Host", "myhost.com");
post.setHeader("Authorization",getB64Auth());
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("data[body]", "test"));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
ent.setContentEncoding("UTF-8");
post.setEntity(ent);
post.setURI(new URI("http://myhost.com/test.php"));
HttpResponse response =client.execute(post);

Method getB64Auth() returns "login:password" encoded using Base64 like: "YnxpcYRlc3RwMTulHGhlSGs=" but it's not important.

方法getB64Auth()返回使用Base64编码的“login:password”,如:“YnxpcYRlc3RwMTulHGhlSGs =”,但这并不重要。

This is a piece of lighttpd's error.log when above code is invoked on pure java:

当在纯java上调用上面的代码时,这是一个lighttpd的error.log:

2011-02-23 15:37:36: (request.c.304) fd: 8 request-len: 308
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-type: text/html
Transfer-Encoding: chunked

and record from access.log (IP changed):

并从access.log记录(IP已更改):

1.1.1.1 myhost.com - [23/Feb/2011:15:37:36 +0100] "POST /test.php HTTP/1.1" 200 32 "-" "Apache-HttpClient/4.1 (java 1.5)"

When the same code is invoked on android, I get this in logs:

当在android上调用相同的代码时,我在日志中得到这个:

POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=

Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
Expect: 100-Continue


2011-02-23 15:45:10: (response.c.128) Response-Header:
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close

access.log:

access.log的:

1.1.1.1 - - [23/Feb/2011:15:45:10 +0100] "POST /test.php HTTP/1.1" 400 349 "-" "Apache-HttpClient/4.1 (java 1.5)"

How to get Authorization with POST working on android? When I use HttpURLConnection instead of HttpClient it is no difference.

如何使用POST在android上进行授权?当我使用HttpURLConnection而不是HttpClient时,它没有区别。

2 个解决方案

#1


57  

Thanks to Samuh for a hint :) There was an extra newline character inserted which has no means in GET requests, but matters in POST ones. This is proper way to generate Authorization header in android (in getB64Auth in this case):

感谢Samuh的提示:)插入了一个额外的换行符,它在GET请求中没有任何意义,但在POST中却很重要。这是在android中生成Authorization标头的正确方法(在本例中为getB64Auth):

 private String getB64Auth (String login, String pass) {
   String source=login+":"+pass;
   String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE|Base64.NO_WRAP);
   return ret;
 }

The Base64.NO_WRAP flag was lacking.

缺少Base64.NO_WRAP标志。

#2


3  

use simply this :

使用这个:

String authorizationString = "Basic " + Base64.encodeToString(
                        ("your_login" + ":" + "your_password").getBytes(),
                        Base64.NO_WRAP); //Base64.NO_WRAP flag
                post.setHeader("Authorization", authorizationString);

#1


57  

Thanks to Samuh for a hint :) There was an extra newline character inserted which has no means in GET requests, but matters in POST ones. This is proper way to generate Authorization header in android (in getB64Auth in this case):

感谢Samuh的提示:)插入了一个额外的换行符,它在GET请求中没有任何意义,但在POST中却很重要。这是在android中生成Authorization标头的正确方法(在本例中为getB64Auth):

 private String getB64Auth (String login, String pass) {
   String source=login+":"+pass;
   String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE|Base64.NO_WRAP);
   return ret;
 }

The Base64.NO_WRAP flag was lacking.

缺少Base64.NO_WRAP标志。

#2


3  

use simply this :

使用这个:

String authorizationString = "Basic " + Base64.encodeToString(
                        ("your_login" + ":" + "your_password").getBytes(),
                        Base64.NO_WRAP); //Base64.NO_WRAP flag
                post.setHeader("Authorization", authorizationString);