Почему ответ, который я получаю от reCAPTCHA API, равен нулю?

#android #kotlin #recaptcha #safetynet-api

Вопрос:

Я использую SafetyNet reCAPTCHA API в моем Activity , и я разбил вызов API на следующее: Repository класс, interface который выполняет POST вызов, data class который хранит JSON полученный ответ, ViewModel а Success также класс слушателя и класс Failure слушателя в моем Activity .

Repository :

 class RecaptchaRepository {
    fun doRecaptchaValidation(
        @NonNull baseUrl: String,
        @NonNull response: String,
        @NonNull key: String
    ): LiveData<RecaptchaVerifyResponse> {
        val data: MutableLiveData<RecaptchaVerifyResponse> = MutableLiveData()
        val params: MutableMap<String, String> = HashMap()
        params["response"] = response
        params["secret"] = key
        getRecaptchaValidationService(baseUrl).verifyResponse(params)
            .enqueue(object : Callback<RecaptchaVerifyResponse> {
                override fun onResponse(
                    call: Call<RecaptchaVerifyResponse>,
                    response: Response<RecaptchaVerifyResponse>
                ) {
                    data.value = response.body()
                }

                override fun onFailure(call: Call<RecaptchaVerifyResponse>, t: Throwable) {
                    data.value = null
                }

            })
        return data
    }

    private fun getRecaptchaValidationService(@NonNull baseUrl: String): RecaptchaVerificationService {
        return getRetrofit(baseUrl).create(
            RecaptchaVerificationService::class.java
        )
    }

    private fun getRetrofit(@NonNull baseUrl: String): Retrofit {
        val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
        val client = OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()
        return Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .baseUrl(baseUrl)
            .client(client)
            .build()
    }
}
 

Interface чтобы вызвать POST :

 interface RecaptchaVerificationService {
    @Headers("Content-Type: application/x-www-form-urlencoded; charset=utf-8")
    @POST("/recaptcha/api/siteverify")
    fun verifyResponse(@QueryMap params: Map<String, String>): Call<RecaptchaVerifyResponse>
}
 

data class генерируется Moshi :
@JsonClass(generateAdapter = true)

 data class RecaptchaVerifyResponse(
    @Json(name = "success")
    val success: Boolean,
    @Json(name = "challenge_ts")
    val challenge_ts: String,
    @Json(name = "apk_package_name")
    val apk_package_name: String,
    @Json(name = "error-codes")
    val error_codes: List<String>
)
 

ViewModel :

 class RecaptchaResponseViewModel(application: Application) : AndroidViewModel(application) {
    fun getmRecaptchaObservable(@NonNull baseUrl: String, @NonNull response: String, @NonNull key: String): LiveData<RecaptchaVerifyResponse> {
        return RecaptchaRepository().doRecaptchaValidation(baseUrl, response, key)
    }
}
 

The SafetyNet API call in my activity’s onCreate method:

 SafetyNet.getClient(this).verifyWithRecaptcha(BuildConfig.RECAPTCHA_SITE_KEY)
    .addOnSuccessListener(RecaptchaSuccessListener())
    .addOnFailureListener(RecaptchaFailureListener())
 

And the Success listener class and Failure listener class, also in my Activity :

 private inner class RecaptchaSuccessListener : OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse> {
    override fun onSuccess(recaptchaTokenResponse: SafetyNetApi.RecaptchaTokenResponse) {
        val userResponseToken: String = recaptchaTokenResponse.tokenResult!!
        if (userResponseToken.isNotEmpty()) {
            recaptchaViewModel.getmRecaptchaObservable("https://www.google.com", userResponseToken, BuildConfig.RECAPTCHA_SECRET_KEY).observe(this@LoginActivity, object : Observer<RecaptchaVerifyResponse> {
                override fun onChanged(@Nullable recaptchaVerifyResponse: RecaptchaVerifyResponse?) {
                    if (recaptchaVerifyResponse != null amp;amp; recaptchaVerifyResponse.success) {
                        // reCAPTCHA successfully worked and verified user is human
                    } else {
                        // reCAPTCHA response validation failed
                    }
                }
            })
        }
    }
}

private inner class RecaptchaFailureListener : OnFailureListener {
    override fun onFailure(@NonNull e: Exception) {
        // Device side validation resulted in no token. Failure
    }
}
 

Now in the Success listener class’s onChanged method, when it checks to see if recaptchaVerifyResponse is not null and if recaptchaVerifyResponse.success is true , it fails because the success , challenge_ts , apk_package_name , and error_codes variables from the data class are all set to null .

Why is that the case? What am I doing wrong that’s causing all the fields to be set to null ?