我在我的中使用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)
}
}
我的活动方法中的SafetyNet
API 调用onCreate
:
SafetyNet.getClient(this).verifyWithRecaptcha(BuildConfig.RECAPTCHA_SITE_KEY)
.addOnSuccessListener(RecaptchaSuccessListener())
.addOnFailureListener(RecaptchaFailureListener())
还有Success
监听器类和Failure
监听器类,也在我的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 && 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
}
}
现在在Success
侦听器类的onChanged
方法中,当它检查 if recaptchaVerifyResponse
is notnull
和 if recaptchaVerifyResponse.success
istrue
时,它会失败,因为success
, challenge_ts
,apk_package_name
和error_codes
中的变量data class
都设置为null
。
为什么会这样?我做错了什么导致所有字段都设置为null
?