Get Response String/JSON
Gorebar opened this issue · 6 comments
How to get the response JSON or String from this signed request?
Hey,
this library depends on OkHttp. You usually use it along with Retrofit.
We do the signing with the help of a okhttp3.Interceptor
which you can add to Retrofit on initialization.
Do you need more information?
Hey,
this library depends on OkHttp. You usually use it along with Retrofit.
We do the signing with the help of aokhttp3.Interceptor
which you can add to Retrofit on initialization.Do you need more information?
Could you send me a working example singing and getting the response JSON from a request? This is making me crazy...
Always I am getting as unusual canonical string.
I don't have a example lying around here, but this is how our interceptor looks like
class AwsInterceptor constructor(
private val credentialsProvider: CredentialsProvider,
private val signer: OkHttpAwsV4Signer
) : Interceptor {
private val dateFormat: ThreadLocal<SimpleDateFormat>
init {
dateFormat = object : ThreadLocal<SimpleDateFormat>() {
override fun initialValue(): SimpleDateFormat {
val localFormat = SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US)
localFormat.timeZone = TimeZone.getTimeZone("UTC")
return localFormat
}
}
}
override fun intercept(chain: Interceptor.Chain): Response =
chain.run {
val newRequest = request().newBuilder()
.addRequiredHeaders(request().host)
.build()
.sign()
proceed(newRequest)
}
/**
* Some headers are needed for the signing to work. This method makes sure they're part
* of the request
*/
private fun Request.Builder.addRequiredHeaders(host: String) =
apply {
header("x-amz-date", dateFormat.format(Date())
header("host", host)
val sessionToken = credentialsProvider.sessionToken
if (!sessionToken.isNullOrBlank())
header("x-amz-security-token", sessionToken)
}
private fun Request.sign() =
signer.sign(
this,
credentialsProvider.accessKeyId,
credentialsProvider.secretAccessKey
)
private fun ThreadLocal<SimpleDateFormat>.format(date: Date): String = get()!!.format(date)
private val Request.host: String
get() = url().host()
}
Then you you need to create your Retrofit instance somehow like this
val okhttpClient = OkHttpClient.Builder()
.addInterceptor(AwsInterceptor(...)) // add your dependencies
.build()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create()) // We use Moshi for the json deserialization
.addCallAdapterFactory(ErrorCallAdapterFactory
.create(RxJava2CallAdapterFactory.create()))
.build();
And the rest is how you use Retrofit usually.
I hope that helps?
The same error... Im getting always the next response:
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
The canonical String is wrong.
Are you sure you are using the right credentials?
I guess this can vary on our setup, but this is how it works for us:
On login we get the auth token of the user.
With the auth token we can query for the accessKeyId
, secretAccessKey
and a short lived sessionToken
from our backend, which we use to sign the requests as you can see above.
The session token expires after a while, for this case we have another intercepter which listens for this error and refreshes the signing credentials.
It is working now, I was using wrong credentials. Thank you so much.