Search code examples
node.jsretrofit2okhttpfido-u2f

Retrofit not attaching body to request


I'm building a U2F-compliant client that simply needs to send a JSON object with the following structure to a POST URL:

{
  challenge: [Base64-encoded String of 32 bytes],
  registrationData: [Base64-encoded String of variable bytes]
}

Here is an excerpt of my code, which runs fine and throws no errors:

import okhttp3.FormBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public interface Registration {
  @POST("register")
  Call<ResponseBody> register(@Body RequestBody body);
}

private void sendRegistrationResponse(String baseURL, String challenge, String data) {
  RequestBody data = new FormBody.Builder()
                    .add("challenge", challengeB64)
                    .add("registrationData", data)
                    .build();

  Retrofit retro = new Retrofit.Builder()
                    .baseUrl(info.getString("baseURL"))
                    .build();

  U2FServices.Registration reg = retro.create(U2FServices.Registration.class);
  Call<ResponseBody> regCall = reg.register(data);
  regCall.enqueue(this);
}

The debugging server is built with Node, and its POST "register" route is successfully called by the client every time. The issue is, the body of the request is always empty.

exports.register = function (req, res) {
  var body = req.body; // {}
}

I imagine the issue lies with the FormBody.Builder(), but I can't find any documentation or code giving a clear example on how it works. Any help is greatly appreciated!


Solution

  • Let's try this - (hope your node server is expecting application/json) or else we need to change that part.

    RequestBody data = RequestBody.create(MediaType.parse("application/json"), stringJson);
    

    Apparently, FormBody's default media type is "application/x-www-form-urlencoded" and if your node server is not expecting this request type, it might fail.

    If you can look up your node's config, it is good to check it up to make sure what media type that a request should form with.

    This is an example of node with express server's config.

    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    

    This node server can expect both json and form url encoded.

    Let me know if this works or not.