I am creating a backend endpoint to handle user login. Part of the login is a Google reCaptcha.
I am also creating Postman collections to test the backed api's. I have the following:
AuthenticationResource.java
@POST
@Path("login")
@ApiOperation(value="Login a user with a username and password and return a jwt")
@ApiResponses({
@ApiResponse(code=200, message="Success"),
@ApiResponse(code=404, message="Not Found")
})
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response login(@ApiParam(required = true) UserLoginDTO userLogin, @Context HttpServletRequest request) {
try {
HttpSession session = request.getSession(true);
logger.info("login: "+userLogin.getUsername());
String username = userLogin.getUsername();
String passwordPlainText = userLogin.getPassword();
String clientRemoteAddr = request.getRemoteAddr();
boolean captchaVerified = VerifyRecaptcha.verify(userLogin.getRecaptcha());
if (!captchaVerified) {
logger.severe("Invalid captcha");
return Response.status(Response.Status.BAD_REQUEST).entity("Invalid captcha").build();
}
VerifyRecaptcha.java
public class VerifyRecaptcha {
private static final Logger logger = Logger.getLogger(VerifyRecaptcha.class.getName());
public static final String url = "https://www.google.com/recaptcha/api/siteverify";
public static final String secret = "my-seceret-key";
private final static String USER_AGENT = "Mozilla/5.0";
public static boolean verify(String gRecaptchaResponse) throws IOException {
if (gRecaptchaResponse == null || "".equals(gRecaptchaResponse)) {
return false;
}
try{
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String postParams = "secret=" + secret + "&response="
+ gRecaptchaResponse;
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
logger.info("\nSending 'POST' request to URL : " + url);
logger.info("Post parameters : " + postParams);
logger.info("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
logger.info(response.toString());
//parse JSON response and return 'success' value
JsonReader jsonReader = Json.createReader(new StringReader(response.toString()));
JsonObject jsonObject = jsonReader.readObject();
jsonReader.close();
return jsonObject.getBoolean("success");
}catch(Exception e){
logger.warning("invalid recaptcha: "+gRecaptchaResponse+". "+e.getMessage());
e.printStackTrace();
return false;
}
}
}
Postman
POST https://localhost:8443/corporateInterface/rest/user/login
Body
{
"password": "password",
"username": "richard",
"recaptchaResponse": "sitekey"
}
Result
Response Code : 200
{ "success": false, "error-codes": [ "invalid-input-response" ]}
Invalid captcha
As you can see, the call to https://www.google.com/recaptcha/api/siteverify returns a 200, but success is false.
Question
Is it possible to test the reCaptcha with Postman? Or will Google not validate a Postman request? If so, what am I doing wrong?
POST to https://www.google.com/recaptcha/api/siteverify
Set content type header (Content-Type) : application/x-www-form-urlencoded
In your body you have to set the secret and response keys.
The response value must be obtained beforehand via form submit, to get $_POST["g-recaptcha-response"];
Success response :
{
"success": true,
"challenge_ts": "timestamp of challenge",
"hostname": "yourhostname"
}
Having that the siteverify will return the result of the check as if you were doing the verification
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With