We are implementing a request signing mechanism for one of our customer banking apps and we use combination of OkHttp and Retrofit. The technical flow is supposed to go like this:
byte[])byte[] using our signing mechanism based on the PIN code valueWe were looking for a way to obtain raw HTTP body data and add HTTP header based on data and PIN code value. The interceptors seemed like a nice way to go around the problem. However, we didn't find any clean way to pass our signing mechanism context data to the filter - we only get request related information as a part of the "chain" object.
It would be nice to have some clean way to pass custom context to interceptor method...
Have you considered creating a new interceptor with the context information for each request you make that requires it?
For example:
private void makePayment(String pin) {
// create a new client for every request
final OkHttpClient pinClient = client.newBuilder()
.addNetworkInterceptor(new CustomSigningInterceptor(context, pin))
.build();
final Request paymentRequest = // construct request
pinClient.newCall(paymentRequest).execute();
// let pinClient go out of scope
}
I imagine this request is not performed more than a handful of times per app use so it's not a particularly heavyweight solution and it's pretty well contained to the parts of the application that need it.
@coreynicholson Yes, this could work for us - it just would be nice to be able to do this in some better way.
@swankjesse While this could work in the blog post scenario, in our case it feels a bit awkward. We would have to pass a plain-text PIN code / cryptographic keys as HTTP header and rely on them being removed correctly before the request is sent. Not removing the headers correctly could lead to little disaster.
@petrdvorak you don鈥檛 have to pass the secrets, just an identifier for them. Plus some shared place to exchange the identifier back.
@Singleton
class Locker {
/** Returns a unique identifier like "11". */
String put(Object v);
/** Returns the object put with this identifier. */
Object take(String key)
}
Actually, I don't think you need an interceptor at all, can't you get the request body as bytes from the RequestBody object using the abstract void writeTo(okio.BufferedSink sink) method then add the header you want when constructing the request object?
No action for us to take on this.
Most helpful comment
Does this work?
https://publicobject.com/2016/01/17/sneaking-data-into-an-okhttp-interceptor/