在Android應用中使用Google reCAPTCHA
在本教程中,我們將學習Google reCaptcha的工作流程,并將其集成到我們的Android應用中。愛掏網 - it200.comGoogle的reCaptcha可以保護我們的應用免受惡意流量的侵害。愛掏網 - it200.com它是使用SafetyNet API實現的。愛掏網 - it200.com
Google reCAPTCHA通過Android應用程序、SafetyNet服務器和您的服務器之間的網絡調用來進行驗證。愛掏網 - it200.com
- Android應用程序使用 站點密鑰 向 SafetyNet 服務器發出reCAPTCHA驗證請求。愛掏網 - it200.com
- SafetyNet 服務器使用站點 密鑰 生成驗證碼令牌的響應,并將其發送給Android應用程序。愛掏網 - it200.com
- 驗證碼令牌通過 密鑰 發送到您的服務器進行驗證。愛掏網 - it200.com
- 您的Android服務器使用 SafetyNet 服務器發送請求,使用Secret 密鑰 驗證驗證碼令牌。愛掏網 - it200.com
- SafetyNet 驗證令牌響應,并將結果返回為成功或失敗。愛掏網 - it200.com
- 您的Android服務器通過驗證令牌將結果返回給Android應用程序,并返回結果為成功或失敗。愛掏網 - it200.com
生成reCAPTCHA網站密鑰和秘密密鑰:
在創建API密鑰之前,請仔細閱讀API服務條款 https://developers.google.com/terms/ 。愛掏網 - it200.com
- 注冊Android reCAPTCHA網站 https://g.co/recaptcha/androidsignup 。愛掏網 - it200.com
- 提供標簽、包名和接受reCAPTCHA條款和服務的輸入詳細信息。愛掏網 - it200.com
標簽 :這是您的密鑰的唯一標簽。愛掏網 - it200.com您可以使用您公司或組織的名稱。愛掏網 - it200.com 包名 :這是您的安卓應用程序的包名。愛掏網 - it200.com
- 網站密鑰、密鑰、客戶端集成代碼和服務器端代碼在下一頁生成。愛掏網 - it200.com
Android集成Google reCAPTCHA示例
讓我們創建一個在Android應用程序中集成Google reCAPTCHA的示例。愛掏網 - it200.com
build.gradle
在build.gradle文件中添加以下SafetyNet和Volley依賴項。愛掏網 - it200.com
dependencies {
implementation 'com.google.android.gms:play-services-safetynet:15.0.1'
implementation 'com.android.volley:volley:1.0.0'
}
AndroidManifest.xml
在AndroidManifest.xml文件中添加互聯網權限
<uses-permission android:name="android.permission.INTERNET" />
activity_main.xml
將以下代碼添加到activity_main.xml文件中。愛掏網 - it200.com
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.javatpoint.com.googlerecaptcha.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Google Recaptcha"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.436"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.017" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="52dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Verify captcha"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
MainActivity.java
將以下代碼添加到MainActivity.java類文件中。愛掏網 - it200.com在這個類中,我們與SafetyNet服務器進行客戶端集成,并以JSON字符串形式獲取響應。愛掏網 - it200.com
將SITE_KEY和SECRET_KEY的值替換為您實際的Site Key和Secret Key。愛掏網 - it200.com點擊按鈕時,它調用SafetyNet.getClient()方法獲取Site Key,如果返回成功,則調用handleSiteVerify()進行令牌驗證。愛掏網 - it200.com
Volley庫用于以下目的:
- Volley庫的RequestQueue維護了服務器調用隊列。愛掏網 - it200.com
- StringRequest用于從您的服務器獲取響應的JSON字符串。愛掏網 - it200.com
- setRetryPolicy()方法在時間限制內如果服務器調用失敗則重試。愛掏網 - it200.com
package example.javatpoint.com.googlerecaptcha;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
String TAG = MainActivity.class.getSimpleName();
Button btnverifyCaptcha;
String SITE_KEY = "6LeaN24UAxxxxx_YOUR_SITE_KEY";
String SECRET_KEY = "6LeaN24UAxxxxx_YOUR_SECRET_KEY";
RequestQueue queue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnverifyCaptcha = findViewById(R.id.button);
btnverifyCaptcha.setOnClickListener(this);
queue = Volley.newRequestQueue(getApplicationContext());
}
@Override
public void onClick(View view) {
SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY)
.addOnSuccessListener(this, new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
@Override
public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
if (!response.getTokenResult().isEmpty()) {
handleSiteVerify(response.getTokenResult());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
Log.d(TAG, "Error message: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
} else {
Log.d(TAG, "Unknown type of error: " + e.getMessage());
}
}
});
}
protected void handleSiteVerify(final String responseToken){
//it is google recaptcha siteverify server
//you can place your server url
String url = "https://www.google.com/recaptcha/api/siteverify";
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if(jsonObject.getBoolean("success")){
//code logic when captcha returns true Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getBoolean("success")),Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),String.valueOf(jsonObject.getString("error-codes")),Toast.LENGTH_LONG).show();
}
} catch (Exception ex) {
Log.d(TAG, "JSON exception: " + ex.getMessage());
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error message: " + error.getMessage());
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("secret", SECRET_KEY);
params.put("response", responseToken);
return params;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
50000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
}
}
輸出: