How to set Google Recaptcha Enterprise verification Using Api Key In Java Language?

3.7k views Asked by At

I am not being able to connect to

POST url: https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments?key=API_KEY

JSON BODY:

{ "event": { "token": "TOKEN", "siteKey": "KEY", "expectedAction": "USER_ACTION" } }

using my code, I keep getting ECONNRESET error. When I am hitting the above connection directly with postman, I am able to connect but when I am trying to use postForObject in code it refuses and throws error. I have even tried connecting using create assessment for Java provided in documention:

import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
import com.google.recaptchaenterprise.v1.Assessment;
import com.google.recaptchaenterprise.v1.CreateAssessmentRequest;
import com.google.recaptchaenterprise.v1.Event;
import com.google.recaptchaenterprise.v1.ProjectName;
import com.google.recaptchaenterprise.v1.RiskAnalysis.ClassificationReason;
import java.io.IOException;

public class CreateAssessment {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectID = "project-id";
    String recaptchaSiteKey = "recaptcha-site-key";
    String token = "action-token";
    String recaptchaAction = "action-name";

    createAssessment(projectID, recaptchaSiteKey, token, recaptchaAction);
  }

  /**
   * Create an assessment to analyze the risk of an UI action. Assessment approach is the same for
   * both 'score' and 'checkbox' type recaptcha site keys.
   *
   * @param projectID : GCloud Project ID
   * @param recaptchaSiteKey : Site key obtained by registering a domain/app to use recaptcha
   *     services. (score/ checkbox type)
   * @param token : The token obtained from the client on passing the recaptchaSiteKey.
   * @param recaptchaAction : Action name corresponding to the token.
   */
  public static void createAssessment(
      String projectID, String recaptchaSiteKey, String token, String recaptchaAction)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `client.close()` method on the client to safely
    // clean up any remaining background resources.
    try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {

      // Set the properties of the event to be tracked.
      Event event = Event.newBuilder().setSiteKey(recaptchaSiteKey).setToken(token).build();

      // Build the assessment request.
      CreateAssessmentRequest createAssessmentRequest =
          CreateAssessmentRequest.newBuilder()
              .setParent(ProjectName.of(projectID).toString())
              .setAssessment(Assessment.newBuilder().setEvent(event).build())
              .build();

      Assessment response = client.createAssessment(createAssessmentRequest);

      // Check if the token is valid.
      if (!response.getTokenProperties().getValid()) {
        System.out.println(
            "The CreateAssessment call failed because the token was: "
                + response.getTokenProperties().getInvalidReason().name());
        return;
      }

      // Check if the expected action was executed.
      // (If the key is checkbox type and 'action' attribute wasn't set, skip this check.)
      if (!response.getTokenProperties().getAction().equals(recaptchaAction)) {
        System.out.println(
            "The action attribute in reCAPTCHA tag is: "
                + response.getTokenProperties().getAction());
        System.out.println(
            "The action attribute in the reCAPTCHA tag "
                + "does not match the action ("
                + recaptchaAction
                + ") you are expecting to score");
        return;
      }

      // Get the reason(s) and the risk score.
      // For more information on interpreting the assessment,
      // see: https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
      for (ClassificationReason reason : response.getRiskAnalysis().getReasonsList()) {
        System.out.println(reason);
      }

      float recaptchaScore = response.getRiskAnalysis().getScore();
      System.out.println("The reCAPTCHA score is: " + recaptchaScore);

      // Get the assessment name (id). Use this to annotate the assessment.
      String assessmentName = response.getName();
      System.out.println(
          "Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));
    }
  }
}

Here it asking me to set environment variable GOOGLE_APPLICATION_CREDENTIALS, but since I want to use apiKey. I should be able to connect only using apiKey and not mentioning credentials. Can anyone help me in how to setup verification using apiKey, any help is appreciated.

2

There are 2 answers

0
Reed S On

I came across this post while trying to solve my own issues with integrating ReCaptcha Enterprise.

From Google:

Note: If you set up reCAPTCHA Enterprise on a third-party cloud or on-premises that do not support service accounts, you cannot use the reCAPTCHA Enterprise Client Libraries to create an assessment

So, it seems the Google APIs do not support using an API key. After some frustration with deserialization while trying to use the Google API classes, I simply created my own equivalent classes which implement the Serializable interface and contain the same fields as the Google API equivalents (eg. MyAssessment is equivalent to the Google API Assessment class).

You might try something similar to the following:

public static void createAssessment(String projectId, String siteKey, String token, String action, String apiKey) {
    String format = "https://recaptchaenterprise.googleapis.com/v1/projects/%s/assessments";
    // Create the URI using the key as a Query parameter
    URI uri = UriComponentsBuilder
        .fromUriString(String.format(format, projectId))
        .queryParam("key", apiKey)
        .build()
        .toUri();
    
    // Build the request
    MyEvent event = new MyEvent(siteKey, token, action);
    MyAssessmentRequest assessmentRequest = new MyAssessmentRequest(event);
    RequestEntity<MyAssessmentRequest> req = RequestEntity.post(uri).body(assessment);

    // Make the call
    ResponseEntity<MyAssessmentResponse> resp = new RestTemplate().exchange(req, MyAssessmentResponse.class);

    // Process the response
    // MyRiskAnalysis ra = response.getBody().getRiskAnalysis();
    // MyTokenProperties tp = response.getBody().getTokenProperties();
    // MyEvent e = response.getBody().getEvent();
}

Hope this helps!

1
ppr On

This is working for me:

        final RecaptchaEnterpriseServiceSettings settings = RecaptchaEnterpriseServiceSettings.newBuilder()
            
            .setCredentialsProvider(NoCredentialsProvider.create())
            .setHeaderProvider(FixedHeaderProvider.create("x-goog-api-key", "your api key"))
            .build();
      try (RecaptchaEnterpriseServiceClient client = 
              RecaptchaEnterpriseServiceClient.create(settings)) {...}

x-goog-api-key is mentioned here: https://cloud.google.com/docs/authentication/api-keys