Spotify: post to api/token gives bad request but works in curl

Viewed 667

I'm trying to get an access token from the spotify web api through the Authorization Code Flow. When doing the request in curl, it gives me back the token as expected:

curl -H "Authorization: Basic Mj...zk=" -d grant_type=authorization_code -d code=AQ...Ew -d redirect_uri=http://localhost:8081/callback https://accounts.spotify.com/api/token

However, when I try to do the same request in java code, I get a 400 bad request:

    final String url = "https://accounts.spotify.com/api/token";

    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("grant_type", "authorization_code"));
    params.add(new BasicNameValuePair("code", req.getParameter("code")));
    params.add(new BasicNameValuePair("redirect_uri ", "http://localhost:8081/callback"));


    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
    httpPost.setHeader(HttpHeaders.AUTHORIZATION,"Basic " +  Base64.encodeBase64String(("2...0" + ":" + "4...9").getBytes()));
    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");

    CloseableHttpResponse response = client.execute(httpPost);
    System.out.println(response);

This is the error response I get:

HttpResponseProxy{HTTP/1.1 400 Bad Request [Server: nginx, Date: Fri, 06 Oct 2017 21:20:39 GMT, Content-Type: application/json, Content-Length: 68, Connection: keep-alive, Keep-Alive: timeout=600] ResponseEntityProxy{[Content-Type: application/json,Content-Length: 68,Chunked: false]}}

What am I missing or doing wrong?

1 Answers

Fixed it myself by using a StringEntity instead of the UrlEncodedFormEntity:

    final String url = "https://accounts.spotify.com/api/token";
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);

    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
    httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.encodeBase64String(("2...0" + ":" + "4...9").getBytes()));
    StringEntity data = new StringEntity("grant_type=authorization_code&&code=" + req.getParameter("code") + "&&redirect_uri=http://localhost:8081/callback");
    httpPost.setEntity(data);

    HttpResponse response = client.execute(httpPost);
Related