英文:
Signature issue while multipart "posting" with Retrofit on Android
问题
I am having a problem trying to send data to my server using multipart/form-data
If I send only 2 parts (file included) I get an error 400 (saying I am missing the 2 others parts)
but if I send 3 or 4 parts I get an error 401 because my server respond with a signature issue.
here is my code.
My Interface:
@POST("api/{id}/edit")
@Multipart
fun postMultipart(
@Path("id") id: Int,
@Part commissioner: MultipartBody.Part,
@Part commissioning: MultipartBody.Part,
@Part file: MultipartBody.Part?,
@Part commissioningDate: MultipartBody.Part
): Call<ResponseBody>
So If I only send file
and for example commissioner
my server is responding 400 but if I send file
and commissioner
and commissioning
my server is responding 401
I also tried MultipartBody.Part
or RequestBody
for other parts than the file (same result)
My AsyncTask making the call:
val interface = RetrofitSignedClient().getClient().create(Interface::class.java)
val f = getFile(context, fileUri)
val requestFile: RequestBody = f.asRequestBody()
val fileBody: MultipartBody.Part = MultipartBody.Part.createFormData("file", f.name, requestFile)
val commissionerIdPart =
MultipartBody.Part.createFormData("commissioner", commissioner)
val commissioningPart =
MultipartBody.Part.createFormData("commissioning", commissioning)
val datePart =
MultipartBody.Part.createFormData("commissioningDate", date)
val response =
interface.postMultipart(
id = id,
commissioner = commissionerIdPart,
commissioning = commissioningPart,
file = fileBody,
commissioningDate = datePart
).execute()
The retrofit client:
val consumer = OkHttpOAuthConsumer(consumerKey, consumerSecret)
consumer.setTokenWithSecret(token, secret)
val client = OkHttpClient.Builder()
.addInterceptor(SigningInterceptor(consumer)).build()
return Retrofit.Builder().baseUrl(WS_HOSTNAME_PROJECT)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.client(client)
.build()
For the 401 error, on phone logs I have 401 Unauthorized {"message":"An authentication exception occurred."}
and on server side:
Verification of signature failed (signature base string was "POST&http%3A%2F%2Fmy.server.address%2Fapi%2FID%2Fedit&commissioner%3D110000000292%26commissioning%3D0%26oauth_consumer_key%3DXXXX%26oauth_nonce%3DXXXX%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3DXXX%26oauth_token%3DXXXX%26oauth_version%3D1.0"). with Array ( [0] => 7992a0f54cc2104fec647c75a9aa8317 [1] => 1b1fea099c727b89d9c0cb9d9a618608 [2] => access ) -- Signature verification failed (HMAC-SHA1)
Am I missing something?
英文:
I am having a problem trying to send data to my server using multipart/form-data
If I send only 2 parts (file included) I get an error 400 (saying I am missing the 2 others parts)
but if I send 3 or 4 parts I get an error 401 because my server respond with a signature issue.
here is my code.
My Interface:
@POST("api/{id}/edit")
@Multipart
fun postMultipart(
@Path("id") id: Int,
@Part commissioner: MultipartBody.Part,
@Part commissioning: MultipartBody.Part,
@Part file: MultipartBody.Part?,
@Part commissioningDate: MultipartBody.Part
): Call<ResponseBody>
So If I only send file
and for example commissioner
my server is responding 400 but if I send file
and commissioner
and commissioning
my server is responding 401
I also tried MultipartBody.Part
or RequestBody
for other parts than the file (same result)
My AsyncTask making the call:
val interface = RetrofitSignedClient().getClient().create(Interface::class.java)
val f = getFile(context, fileUri)
val requestFile: RequestBody = f.asRequestBody()
val fileBody: MultipartBody.Part = MultipartBody.Part.createFormData("file", f.name, requestFile)
val commissionerIdPart =
MultipartBody.Part.createFormData("commissioner", commissioner)
val commissioningPart =
MultipartBody.Part.createFormData("commissioning", commissioning)
val datePart =
MultipartBody.Part.createFormData("commissioningDate", date)
val response =
interface.postMultipart(
id = id,
commissioner = commissionerIdPart,
commissioning = commissioningPart,
file = fileBody,
commissioningDate = datePart
).execute()
The retrofit client:
val consumer = OkHttpOAuthConsumer(consumerKey, consumerSecret)
consumer.setTokenWithSecret(token, secret)
val client = OkHttpClient.Builder()
.addInterceptor(SigningInterceptor(consumer)).build()
return Retrofit.Builder().baseUrl(WS_HOSTNAME_PROJECT)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.client(client)
.build()
For the 401 error, on phone logs I have 401 Unauthorized {"message":"An authentication exception occurred."}
and on server side:
Verification of signature failed (signature base string was "POST&http%3A%2F%2Fmy.server.address%2Fapi%2FID%2Fedit&commissioner%3D110000000292%26commissioning%3D0%26oauth_consumer_key%3DXXXX%26oauth_nonce%3DXXXX%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3DXXX%26oauth_token%3DXXXX%26oauth_version%3D1.0"). with Array ( [0] => 7992a0f54cc2104fec647c75a9aa8317 [1] => 1b1fea099c727b89d9c0cb9d9a618608 [2] => access ) -- Signature verification failed (HMAC-SHA1)
Am I missing something?
答案1
得分: 0
问题实际上出现在服务器端。
如果只有一个参数存在,使用的库会对请求进行签名,而如果存在两个或更多参数,则会带上参数一起签名。
英文:
In fact the issue was on server side.
The lib used signed the request without params if only one is present and with params if 2 or more are present.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论