0
votes

I am sending my token as Authorization in Retrofit but I always get a 401 code. But if I use the same token in Postman, I can get access. I know I am able to access the webapi because I can Login just fine and able to get the token from the Web Api. Please see my code below:

ApiService Interface

@POST("consolidated/sample")
fun sample(@Header("Authorization") token: String): Call<ResponseBody>

Calling the Service

private fun pushTransactionsToWebApi() {
       val vApiService = ApiServiceBuillder.buildService(ApiService::class.java)
        CoroutineScope(Main).launch {
            var token = SharedDataManager.getInstance(context!!).applicationToken
            var tokenArr = token!!.split(':')
            responseFromApi = tokenArr[1] ==> I use this so I can remove the word "token" at the beginning of the token string
            token = "Bearer ${responseFromApi}"
            Log.i("TAG", "${token}") ==> ####

            val call = vApiService.sample(token)
            if(!call.isExecuted) {
                call.enqueue(object : Callback<ResponseBody>{
                    override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                        responseFromApi = t.message
                    }

                    override fun onResponse(
                        call: Call<ResponseBody>,
                        response: Response<ResponseBody>
                    ) {
                        if(response.isSuccessful){
                            Toast.makeText(context, "We are OK", Toast.LENGTH_LONG).show()

                        } else {
                            progressDialog!!.dismiss()

                            Toast.makeText(context, "We are NOT OK", Toast.LENGTH_LONG).show()
                        }
                    }
                })
            }
        }
    }

### => Result in my Log.i()

2020-04-08 13:03:09.235 14185-14185/com.kotlin.ambulantlcs I/TAG: Bearer "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4ODgwNSIsInVzZXJJZCI6IjEiLCJmaXJzdE5hbWUiOiJKdWFuIiwibWlkZGxlTmFtZSI6IkEuIiwibGFzdE5hbWUiOiJEZWxhIENydXoiLCJ0cmFuc2FjdGlvbktleSI6IjJkNjZlYzMxLWI5M2ItNDI2ZC1hMzJlLTM0Yjc4OWE4M2E3OCIsInJldmVudWVEYXRlIjoiMjIvMDMvMjAyMCAyOjI0OjM0IFBNIiwic2hpZnQiOiIyIiwic29zSWQiOiIxMjM0NTYiLCJzb2RJZCI6IjY4IiwicGxhemEiOiI4MDMiLCJoYXNEZXBhcnRlZCI6IkZhbHNlIiwianRpIjoiNjhkMDdmNzEtMThiYy00NmQwLTg3YzEtY2MxMjk4YjgxZDkwIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjpbIlVzZXIiLCJBZG1pbiJdLCJleHAiOjE1ODY0MDg1NzUsImlzcyI6Imh0dHA6Ly8xOTIuMTY4LjEuNDo1MDAwIn0.m1mZw79KLIxq4pZPmBRbN7TjILvhvbUIJOCWDEM8I-k"}

If I paste this in my Postman, I can get access

enter image description here

What do I need to do? Thank you!

2
Is your ip address accessible from your android device?touhid udoy
is the IP publically available? try if you can get success result in your emulatorSanjeev S
Yes. I can Login Ok that's why I can get the token Sirs. I can Login both in the device and postman.Ibanez1408
You might be missing the user agents and request params, inspect the request on the device and just keep the exact params, you will get the same error on postman tooRavi
Maybe this is a shot in the dark, but I've noticed that your token in logcat contains quotes and a curly brace at the end and it doesn't in postman. Could you print SharedDataManager.getInstance(context!!).applicationToken? I'm guessing this is a JSON like {"token: "..."} and that's why it works splitting on : and would explain why you get your output like that. If so, I can then post an answer explaining how to deserialise this token.Fred

2 Answers

1
votes

From our conversation in the comments, it seems like you're getting a json {"token": "..."} from SharedDataManager.getInstance(context!!).applicationToken. This explains why when you split in : you get printed in the log "..."}.

There are a lot of ways to deserialize json in Android. Here are some options. I think the vanilla way is something like:

val root = JSONObject(SharedDataManager.getInstance(context!!).applicationToken)
val token = root.getString("token")

With this you'll have the token in token.


However, if you already have a json library you could use it. For example, with gson you could do something like:

data class TokenData(
   @SerializedName("token")
   val token: String)

val token = Gson().fromJson(
           SharedDataManager.getInstance(context!!).applicationToken,
           TokenData::class.java)

You can now use token.


With Moshi using the kotlin gen library - com.squareup.moshi:moshi-kotlin-codegen - you can define the above model like:

@JsonClass(generateAdapter = true)
data class TokenData(
   @Json(name = "token")
   val token: String)

// Then get it like:
val token = Moshi.Builder()
        .build()
        .adapter(TokenData::class.java)
        .fromJson(SharedDataManager.getInstance(context!!).applicationToken)

These are just some options. There's also the popular Jackson. Pick the one that suits best your needs. Hope this helps

0
votes
Remove "  " quotes from token
make sure that keys must be same
pass token like as:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4ODgwNSIsInVzZXJJZCI6IjEiLCJmaXJzdE5hbWUiOiJKdWFuIiwibWlkZGxlTmFtZSI6IkEuIiwibGFzdE5hbWUiOiJEZWxhIENydXoiLCJ0cmFuc2FjdGlvbktleSI6IjJkNjZlYzMxLWI5M2ItNDI2ZC1hMzJlLTM0Yjc4OWE4M2E3OCIsInJldmVudWVEYXRlIjoiMjIvMDMvMjAyMCAyOjI0OjM0IFBNIiwic2hpZnQiOiIyIiwic29zSWQiOiIxMjM0NTYiLCJzb2RJZCI6IjY4IiwicGxhemEiOiI4MDMiLCJoYXNEZXBhcnRlZCI6IkZhbHNlIiwianRpIjoiNjhkMDdmNzEtMThiYy00NmQwLTg3YzEtY2MxMjk4YjgxZDkwIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjpbIlVzZXIiLCJBZG1pbiJdLCJleHAiOjE1ODY0MDg1NzUsImlzcyI6Imh0dHA6Ly8xOTIuMTY4LjEuNDo1MDAwIn0.m1mZw79KLIxq4pZPmBRbN7TjILvhvbUIJOCWDEM8I-k