📜  Android 在应用程序中使用Google reCAPTCHA

📅  最后修改于: 2020-10-11 06:01:07             🧑  作者: Mango

在Android应用程序中使用Google reCAPTCHA

在本教程中,我们将学习Google reCaptcha的工作过程并将其集成到我们的Android应用程序中。 Google的reCaptcha保护我们的应用程序免受恶意流量的侵害。它是使用SafetyNet API实现的。

Google reCaptcha的工作:

通过调用Android应用程序,SafetyNet服务器与您的服务器之间的网络调用来验证Google reCAPTCHA。

  • 一个Android应用程序通过Site KeySafetyNet服务器发出请求,以进行reCAPTCHA验证。
  • SafetyNet服务器使用站点密钥通过验证码令牌对Android应用生成响应。
  • 使用密钥将验证码令牌发送到您的服务器以进行验证。
  • 您的Android服务器使得用于验证的验证码令牌使用密钥安全网的请求。
  • SafetyNet验证令牌响应,并以成功或失败返回结果。
  • 您的Android服务器会通过验证令牌来通知Android应用,然后将结果返回为成功还是失败。

生成reCAPTCHA站点密钥和秘密密钥:

在创建API密钥之前,请仔细阅读API服务条款https://developers.google.com/terms/。

  • 注册Android reCAPTCHA网站https://g.co/recaptcha/androidsignup。

  • 提供标签,包装名称的输入详细信息,并接受reCAPTCHA条款和服务。
    标签 :这是密钥的唯一标签。您可以使用公司或组织的名称。
    软件包名称 :这是您的android应用程序的软件包名称。

  • 在下一页生成站点密钥,秘密密钥,客户端集成代码和服务器端代码。

集成Google reCAPTCHA的Android示例

让我们创建一个将Google reCAPTCHA集成到我们的Android应用程序中的示例。

build.gradle

在build.gradle文件中添加以下SafetyNet和Volley依赖项。

dependencies {
    implementation 'com.google.android.gms:play-services-safetynet:15.0.1'
    implementation 'com.android.volley:volley:1.0.0'
}

AndroidManifest.xml

在AndroidManifest.xml文件中添加互联网权限


activity_main.xml

在activity_main.xml文件中添加以下代码。




    

    

MainActivity.java

在MainActivity.java类文件中添加以下代码。在此类中,我们将客户端与SafetyNet服务器进行集成,并以JSON字符串形式获取响应。

用您的实际站点密钥和秘密密钥替换SITE_KEY和SECRET_KEY的值。单击按钮时,如果返回成功,则调用SafetyNet.getClient()方法获取站点密钥,然后调用handleSiteVerify()进行令牌验证。

Volley库用于以下目的:

  • Volley库的RequestQueue在队列中维护服务器调用。
  • StringRequest用于从服务器获取响应作为JSON字符串。
  • 如果setRetryPolicy()方法在规定时间内失败,则重试服务器调用。
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() {
                    @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() {
                    @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 getParams() {
                Map 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);
    }
}

输出: