如何在 Android 中集成 Google reCAPTCHA?
Google reCAPTCHA是 Google 提供的服务之一,用于验证用户是否为机器人。在许多网站和应用程序中都可以看到 Google reCAPTCHA 来验证用户。在本文中,我们将看看 Google reCAPTCHA 在 Android 中的实现。
我们将在本文中构建什么?
我们将构建一个简单的应用程序,在该应用程序中我们将显示一个 Google reCAPTCHA 验证用户按钮,单击该按钮后,我们将向我们的用户显示 Google reCAPTCHA 并对其进行验证。下面给出了一个示例视频,以了解我们将在本文中做什么。请注意,我们将使用Java语言来实现这个项目。
Google reCAPTCHA 的工作
在使用 reCAPTCHA 时,它会多次调用从您的应用程序到 Safety Net 服务器以及从 Safety Net 服务器到您的应用程序。因此,您可以在下图中更详细地了解这些调用。
我们进行 API 调用的步骤:
- 为了在您的应用程序中使用 reCAPTCHA,我们必须生成一个站点密钥和秘密密钥,我们必须将其添加到我们的应用程序中。站点密钥在我们的 Android 应用程序中使用,密钥存储在服务器上。
- 在本网站的帮助下,将生成密钥 reCAPTCHA 并验证用户是否为机器人。
- 通过 reCAPTCHA 进行验证后,我们的应用程序将与我们的验证码服务器通信,并使用您的站点密钥返回响应。
- 现在我们的应用程序将向我们的服务器发送一个令牌,然后我们的服务器将使用我们的密钥向 reCAPTCHA 服务器发送一个令牌。然后 reCAPTCHA 服务器将向我们的服务器发送成功响应,服务器将向我们的应用程序发送成功响应。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Java作为编程语言。
第 2 步:添加 volley 和 Safety Net 的依赖项
因为我们将使用 Google 提供的 API。因此,为了使用这个 API,我们将使用 Volley 来处理我们的 HTTP 请求,并使用一个安全网来连接到 Google reCAPTCHA。
implementation ‘com.android.volley:volley:1.1.1’
implementation ‘com.google.android.gms:play-services-safetynet:15.0.1’
添加此依赖项后,现在同步您的项目,现在我们将着手创建 Google reCAPTCHA 所需的 API 密钥。
第 3 步:生成用于使用 Google reCAPTCHA 的 API 密钥
为了使用 Google reCAPTCHA,我们必须构建两个密钥,例如我们必须用于身份验证的站点密钥和站点密钥。要创建新的 API 密钥,请导航到此 Google 开发人员站点。并参考下图生成 API 密钥。
添加此数据后,接受 reCAPTCHA 条款,然后单击提交选项。
第 4 步:添加 Internet 权限
当我们调用 Google reCAPTCHA 的 API 时,我们必须在AndroidManifest.xml中添加互联网权限。导航到应用程序 > AndroidManifest.xml并将以下代码添加到其中。
XML
XML
Java
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
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 {
// variables for our button and
// strings and request queue.
Button btnverifyCaptcha;
String SITE_KEY = "Enter Your Site Key Here";
String SECRET_KEY = "Enter Your Secret Key Here";
RequestQueue queue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
queue = Volley.newRequestQueue(getApplicationContext());
btnverifyCaptcha = findViewById(R.id.button);
btnverifyCaptcha.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
verifyGoogleReCAPTCHA();
}
});
}
private void verifyGoogleReCAPTCHA() {
// below line is use for getting our safety
// net client and verify with reCAPTCHA
SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY)
// after getting our client we have
// to add on success listener.
.addOnSuccessListener(this, new OnSuccessListener() {
@Override
public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
// in below line we are checking the response token.
if (!response.getTokenResult().isEmpty()) {
// if the response token is not empty then we
// are calling our verification method.
handleVerification(response.getTokenResult());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// this method is called when we get any error.
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
// below line is use to display an error message which we get.
Log.d("TAG", "Error message: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
} else {
// below line is use to display a toast message for any error.
Toast.makeText(MainActivity.this, "Error found is : " + e, Toast.LENGTH_SHORT).show();
}
}
});
}
protected void handleVerification(final String responseToken) {
// inside handle verification method we are
// verifying our user with response token.
// url to sen our site key and secret key
// to below url using POST method.
String url = "https://www.google.com/recaptcha/api/siteverify";
// in this we are making a string request and
// using a post method to pass the data.
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener() {
@Override
public void onResponse(String response) {
// inside on response method we are checking if the
// response is successful or not.
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getBoolean("success")) {
// if the response is successful then we are
// showing below toast message.
Toast.makeText(MainActivity.this, "User verified with reCAPTCHA", Toast.LENGTH_SHORT).show();
} else {
// if the response if failure we are displaying
// a below toast message.
Toast.makeText(getApplicationContext(), String.valueOf(jsonObject.getString("error-codes")), Toast.LENGTH_LONG).show();
}
} catch (Exception ex) {
// if we get any exception then we are
// displaying an error message in logcat.
Log.d("TAG", "JSON exception: " + ex.getMessage());
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// inside error response we are displaying
// a log message in our logcat.
Log.d("TAG", "Error message: " + error.getMessage());
}
}) {
// below is the getParamns method in which we will
// be passing our response token and secret key to the above url.
@Override
protected Map getParams() {
// we are passing data using hashmap
// key and value pair.
Map params = new HashMap<>();
params.put("secret", SECRET_KEY);
params.put("response", responseToken);
return params;
}
};
// below line of code is use to set retry
// policy if the api fails in one try.
request.setRetryPolicy(new DefaultRetryPolicy(
// we are setting time for retry is 5 seconds.
50000,
// below line is to perform maximum retries.
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// at last we are adding our request to queue.
queue.add(request);
}
}
步骤 5:使用 activity_main.xml 文件
导航到app > res > layout > activity_main.xml并将以下代码添加到该文件中。下面是activity_main.xml文件的代码。
XML
第 6 步:使用MainActivity。 Java文件
转到主活动。 Java文件,参考如下代码。下面是MainActivity 的代码。 Java文件。代码中添加了注释以更详细地理解代码。
Java
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
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 {
// variables for our button and
// strings and request queue.
Button btnverifyCaptcha;
String SITE_KEY = "Enter Your Site Key Here";
String SECRET_KEY = "Enter Your Secret Key Here";
RequestQueue queue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
queue = Volley.newRequestQueue(getApplicationContext());
btnverifyCaptcha = findViewById(R.id.button);
btnverifyCaptcha.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
verifyGoogleReCAPTCHA();
}
});
}
private void verifyGoogleReCAPTCHA() {
// below line is use for getting our safety
// net client and verify with reCAPTCHA
SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY)
// after getting our client we have
// to add on success listener.
.addOnSuccessListener(this, new OnSuccessListener() {
@Override
public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
// in below line we are checking the response token.
if (!response.getTokenResult().isEmpty()) {
// if the response token is not empty then we
// are calling our verification method.
handleVerification(response.getTokenResult());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// this method is called when we get any error.
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
// below line is use to display an error message which we get.
Log.d("TAG", "Error message: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
} else {
// below line is use to display a toast message for any error.
Toast.makeText(MainActivity.this, "Error found is : " + e, Toast.LENGTH_SHORT).show();
}
}
});
}
protected void handleVerification(final String responseToken) {
// inside handle verification method we are
// verifying our user with response token.
// url to sen our site key and secret key
// to below url using POST method.
String url = "https://www.google.com/recaptcha/api/siteverify";
// in this we are making a string request and
// using a post method to pass the data.
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener() {
@Override
public void onResponse(String response) {
// inside on response method we are checking if the
// response is successful or not.
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getBoolean("success")) {
// if the response is successful then we are
// showing below toast message.
Toast.makeText(MainActivity.this, "User verified with reCAPTCHA", Toast.LENGTH_SHORT).show();
} else {
// if the response if failure we are displaying
// a below toast message.
Toast.makeText(getApplicationContext(), String.valueOf(jsonObject.getString("error-codes")), Toast.LENGTH_LONG).show();
}
} catch (Exception ex) {
// if we get any exception then we are
// displaying an error message in logcat.
Log.d("TAG", "JSON exception: " + ex.getMessage());
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// inside error response we are displaying
// a log message in our logcat.
Log.d("TAG", "Error message: " + error.getMessage());
}
}) {
// below is the getParamns method in which we will
// be passing our response token and secret key to the above url.
@Override
protected Map getParams() {
// we are passing data using hashmap
// key and value pair.
Map params = new HashMap<>();
params.put("secret", SECRET_KEY);
params.put("response", responseToken);
return params;
}
};
// below line of code is use to set retry
// policy if the api fails in one try.
request.setRetryPolicy(new DefaultRetryPolicy(
// we are setting time for retry is 5 seconds.
50000,
// below line is to perform maximum retries.
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// at last we are adding our request to queue.
queue.add(request);
}
}
添加此代码后,请确保添加我们在您的应用程序中生成的密钥。添加密钥后,运行您的应用程序并查看应用程序的输出。