问题
I have been working around Google OAuth 2.0 with java and got struck with some unknown error during implementation.
The following CURL for POST request works fine:
curl -v -k --header "Content-Type: application/x-www-form-urlencoded" --data "code=4%2FnKVGy9V3LfVJF7gRwkuhS3jbte-5.Arzr67Ksf-cSgrKXntQAax0iz1cDegI&client_id=[my_client_id]&client_secret=[my_client_secret]&redirect_uri=[my_redirect_uri]&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
And produces the required result.
But the following implementation of above POST request in java causes some error and the response in "invalid_request"
Check the following code and point whats going wrong here:(made use of Apache http-components)
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
HttpParams params = new BasicHttpParams();
params.setParameter("code", code);
params.setParameter("client_id", client_id);
params.setParameter("client_secret", client_secret);
params.setParameter("redirect_uri", redirect_uri);
params.setParameter("grant_type", grant_type);
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
post.setParams(params);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);
Tried with URLEncoder.encode( param , "UTF-8")
for each parameter but that too doesn't work.
What might be the cause?
回答1:
You should be using UrlEncodedFormEntity
not setParameter on the post.
It handles the Content-Type: application/x-www-form-urlencoded
header for you too.
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("code", code));
nvps.add(new BasicNameValuePair("client_id", client_id));
nvps.add(new BasicNameValuePair("client_secret", client_secret));
nvps.add(new BasicNameValuePair("redirect_uri", redirect_uri));
nvps.add(new BasicNameValuePair("grant_type", grant_type));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);
回答2:
A bit more generic and unified method for sending UrlEncoded request:
@SneakyThrows
public String postUrlEncoded(String context, Map<String, String> body) {
List<NameValuePair> nameValuePairs = body.entrySet()
.stream()
.map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
HttpResponse response = Request.Post(baseUrl + context)
.bodyForm(nameValuePairs)
.execute().returnResponse();
return EntityUtils.toString(response.getEntity());
}
Ps: it requires fluent Apache HTTP client. Pom dependency:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>${fluent-hc.version}</version>
</dependency>
来源:https://stackoverflow.com/questions/15064037/what-is-wrong-with-this-post-request-implementation