Google Recaptcha V2 integration

Post any questions you have about using the Verj.io Studio, including client and server-side programming with Javascript or FPL, and integration with databases, web services etc.

Moderators: Jon, Steve, Ian, Dave

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

Google Recaptcha V2 integration

#1

Postby ericb » Thu Jan 21, 2016 3:12 pm

I'm attempting to integrate Google Recaptcha V2 into an application running on 4.5.2, however I'm stuck at the server-side integration.

I need to send a POST request to the Recaptcha verification service with two values, "secret" (a key tied to my google account) and "response", which is the value from the client-side verification. I don't know how I can send a POST request from my server-side JS though.

I tried using XmlHttpRequest, however I get an error that it is undefined.
I looked into adding a web service, however it seems to just use XML, and I didn't see any way to send a plain POST request with it.

Did I miss something?
0 x

Steve James
Ebase User
Posts: 331
Joined: Mon Mar 10, 2014 8:34 am

#2

Postby Steve James » Thu Jan 21, 2016 3:38 pm

Hi, try something like this if it can all go server side.

Code: Select all

importPackage(com.ebasetech.xi.api);
importPackage(com.ebasetech.xi.services);
importPackage(java.net);
importPackage(java.io);

var url = new URL("http:theURL.co.uk");
		
var conn1 = url.openConnection();
try
{
	conn1.setRequestMethod("POST");
	conn1.setRequestProperty("Accept", "application/json");
	log("now try to get response code");
	log("conn1.getResponseCode() " + conn1.getResponseCode());
	
	if (conn1.getResponseCode() != 200) 
	{
		log('connection response code - ' + conn1.getResponseCode());
	}

	var input1 = new BufferedInputStream(conn1.getInputStream());

	var json = JSON.parse(getResponseText(input1));
	log("json response " + json);
}
catch (e)
{
	log("exception " + e);
}	

finally
{ 
	if (conn1)
	{
		conn1.disconnect();
	}
}


function getResponseText(inStream) 
{
		// very nice trick from
		// http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
		return new java.util.Scanner(inStream).useDelimiter("\\A").next();
}
0 x

Steve James
Ebase User
Posts: 331
Joined: Mon Mar 10, 2014 8:34 am

#3

Postby Steve James » Thu Jan 21, 2016 3:49 pm

There is also callUrl but that hands control of the browser onto the other site.

http://dev-docs.verj.io/ufs/doc/javadoc ... ng.String)
0 x

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

#4

Postby ericb » Thu Jan 21, 2016 7:07 pm

Thanks Steve, your first post put me on the right track. Just needed to add the input stream part to pass the POST parameters.

In case it can help anyone else in the future, here's the code that worked for me:

Code: Select all

var url = new URL("https://www.google.com/recaptcha/api/siteverify"); 
       
var conn1 = url.openConnection(); 
try 
{ 
	conn1.setRequestMethod("POST"); 
	conn1.setDoOutput(true);
	
	var query = "secret=[recaptchaKey]&response=" + [valueFromRecaptchaField];
	var output = conn1.getOutputStream();
	output.write(toByteArray(query));
	
	var input1 = new BufferedInputStream(conn1.getInputStream()); 
		
	var json = JSON.parse(getResponseText(input1));
		
	if (json["success"] != true) {
		// Do whatever you need to do when the captcha is invalid here

		throw new Error("Invalid captcha");
	}
} catch (e) {
   log("exception " + e); 
} finally {
   if (conn1) {
      conn1.disconnect(); 
   }
}
The toByteArray() function was taken from this answer on Stack Overflow, but any function that converts a string to a byteArray should work.
0 x

kotinkarwak
Ebase User
Posts: 109
Joined: Mon Sep 21, 2015 9:55 pm

#5

Postby kotinkarwak » Tue Jan 26, 2016 3:24 pm

Hi Ericb

Please confirm what/how the following line is implemented.

var query = "secret=[recaptchaKey]&response=" + [valueFromRecaptchaField];

I have tried this assuming that you had the variables defined elsewhere but here I am putting in the values of key and response expected. Is this correct?

var query = "secret=['6LdYeBYTAAAAAI1BAMgmSDNWRnbkasLzuG-ooT3J']&response=" + ['g-recaptcha-response'];

getting error: Invalid capture.

Also, working on localhost at the moment and wondered if you did manage to test for localhost and succeed?
Last edited by kotinkarwak on Fri Jan 29, 2016 8:19 am, edited 1 time in total.
0 x
ebasetech v5

Skype: mateso08
Location: Kenya

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

#6

Postby ericb » Tue Jan 26, 2016 3:36 pm

How is your client-side part set up?

Here's how I did it. I have a non-visible field (visibility: hidden and height: 0) called RECAPTCHA on the page, with the id "ebase_recaptcha", and an html block that includes the Recaptcha script along with the div it needs to work. I have on onready script attached to my submit button that does this:

Code: Select all

$('form').submit(function() {
	$('#ebase_recaptcha').val($('#g-recaptcha-response').val());
});
#g-recaptcha-response is an input generated by the recaptcha code, so I can't assign it to an ebase field (or just don't know how). So instead I take its value when the form is submitted and copy it to my invisible field, which IS an ebase field. That way in my post-click script I can access the response value and pass it to my query that will be send to the Recaptcha server:

Code: Select all

&response=" + fields.RECAPTCHA.value
Hopefully that helps you out.
0 x

kotinkarwak
Ebase User
Posts: 109
Joined: Mon Sep 21, 2015 9:55 pm

#7

Postby kotinkarwak » Tue Jan 26, 2016 4:21 pm

http://screencast.com/t/PmvwS1EnBs3m

Trying this out on a simple login form implemented with two field controls for username and password.
My submit button is build from a horizontal menu with two items (sign-in/cancel)

I have the server side code code as in your example. Now capturing the return on the initial click of "Am not a bot" I am not sure since this appears is needed on the second part of reCaptcha.
I have tried your recent reply of adding a hidden container to hold this value but I am getting null when I check the value.

Your code mentions

$('form').submit(function() { ...

Which I have added on the onready of the menu option for sign-in but no joy.

I think the failure for me is in assigning value to a control using javascript as in statement

Code: Select all

$('#ebase_recaptcha').val($('#g-recaptcha-response').val()); 
I can alert($('#g-recaptcha-response').val()) which shows a long string of data ( assume this is the value we need)
0 x
ebasetech v5

Skype: mateso08
Location: Kenya

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

#8

Postby ericb » Tue Jan 26, 2016 6:01 pm

Do you have jQuery already included?

Start by leaving the field visible so you can see if the value is being copied to it correctly. From there you'll have a better idea of what to debug.
0 x

kotinkarwak
Ebase User
Posts: 109
Joined: Mon Sep 21, 2015 9:55 pm

#9

Postby kotinkarwak » Wed Jan 27, 2016 12:27 pm

Hi Eric,
last hurdles I hope. So far I am getting a chunky string from the recaptcha and in server side, have output the variable query as shown below.
The execution still terminates with a failure in the try body of the code.
Please confirm if your query is of this kinda layout/size?

the code itself is

Code: Select all

//reCaptcha start
	var url = new URL("https://www.google.com/recaptcha/api/siteverify"); 
	print("AK 1");      
	var conn1 = url.openConnection(); 
	print("AK 3");
	try 
	{ 
		print("AK 3");
	   conn1.setRequestMethod("POST"); 
	   print("AK 4");
	   conn1.setDoOutput(true);
	   print("AK 5");

	    print("AK 6");
	    //var query = "secret=[recaptchaKey]&response=" + [valueFromRecaptchaField];
	   var query = "secret='6LdYeBYTAAAAAI1BAMgmSDNWRnbkasLzuG-ooT3J'&response='" + fields.RECAPTCHA.value +"'"; 
	   print("AK 7");
	   var output = conn1.getOutputStream(); 
	   print("AK 8");
	   //output.write(toByteArray(query)); 

	   print("AK QUERY: "+ query);
	   print("AK OUTPUT: "+ output);
	   
	   print("AK A");
	   var input1 = new BufferedInputStream(conn1.getInputStream()); 
	   print("AK B: "+ input1); 
	   var json = JSON.parse(getResponseText(input1)); 
	   print("AK C: "+ json["success"]);    
	   if (json["success"] != true) { 
	      // Do whatever you need to do when the captcha is invalid here 
	
	      throw new Error("XXX Invalid captcha"); 
	   } else if(json["success"] == true) { 
	   		log("AK D:"+json["success"]);
	   }
	} catch (e) { 
	   log("YYY exception " + e); 
	} finally { 
	   if (conn1) { 
	      conn1.disconnect(); 
	   } 
	} 

	//reCaptcha end
	   
TEST OUTPUT FOR QUERY: secret=['6LdYeBYTAAAAAI1BAMgmSDNWRnbkasLzuG-ooT3J'[&response=['03AHJ_Vuui7mifxAHxd1kxcSemnU0gf6PGZ5DxhJ-_sbMjR6B036rt2hRdr3xGZl7i5vHu2anSrWrySTYeLnhzsPbASD-7uOB4zZxRfC4P2NJ7lol4PuMXpuBu5n61dkjEf1ug-y9F9UcjzLrMQiNAQQa1hC4oUZOYGdz561avAmjJCYmSs7Vdaq3SEFoRmDR6d9qBvu0bkqwXDF0CtruOWk0L5n-d0i3MlzYoWyLlG8hlrTkasYtgHi6JGqcVFVP2-7IqBwMus9tVlCrwoBXoTcmTGX-WEAe9IbxLHTxpd49jMzUxVLy9jgaf6x-Anvdmb4foIZUg9RtBZUhtadsVEPQ_OWMQ65hXPQpO7LjyrQV2zvNAkzM6rs42uGvTKOcU5vF_oAoOdEoOMOcBpaAUktF1c-mUFgy7edo1YJjSpdL1X9WR-EsqgO_ijzwRuuIjR4BN5Fb6zcL9hTJHOvArSR2kGaWqWrlkBpCcAGWgyEPMsBzTFwN-SkXQ1abfuabGcrlnyPdkNBoqmikypzGeH3eqYCRwRydmkdlOrcCOYmJT2zCMwpVJ9t5otK1n7pfcdSSuYvR67VlzPTiWWw0xbB4lc4pUlI0PATuz1QwSDKh2URtzNisv7kAtgw5ipc_HmZWcMIkPWq5bmxZzlbvtzkWTjN-SdK3U_i_YJF57dAqOA3rmvcZWbOpE_Ua9_bE94JVKLkVCTMeheYvNW3Z1vja5QMB_1LoDtLvbbdGq3IjdUjIbooN7rMof3Y29lWMnlmWwdeD9NUh0bLuDx_F_2eW1yILP5G_Uoc040cRTeI2uc5tkPl4VMI4kMWN3CpPxzygDffGDt721lgzHmYL3MrVi6YeLuIUlhDACotbMUDGZVtjzol6LsAAe9c_tjrWye8mNL7DUA_uQ-aZnvInldYrmH4RBaa1i34f1NhCXWqMcQK-swcndUBU']
0 x
ebasetech v5

Skype: mateso08
Location: Kenya

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

#10

Postby ericb » Wed Jan 27, 2016 2:00 pm

What error are you getting?
0 x

kotinkarwak
Ebase User
Posts: 109
Joined: Mon Sep 21, 2015 9:55 pm

#11

Postby kotinkarwak » Wed Jan 27, 2016 2:07 pm

Have done an ouput of errocode and reported as below
error-codes: missing-input-response,missing-input-secret

I think my code is not right especially since I commented out the line reading

//output.write(toByteArray(query));

I don't have this function and my assumption is that it is not needed but reading through the code now appears you meant it to be in place.
0 x
ebasetech v5

Skype: mateso08
Location: Kenya

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

#12

Postby ericb » Wed Jan 27, 2016 2:25 pm

Yes, that line is required, as is the toByteArray function..

Referring to my earlier post:
ericb wrote:The toByteArray() function was taken from this answer on Stack Overflow, but any function that converts a string to a byteArray should work.
0 x

kotinkarwak
Ebase User
Posts: 109
Joined: Mon Sep 21, 2015 9:55 pm

#13

Postby kotinkarwak » Wed Jan 27, 2016 3:37 pm

Eric,
I have through trial and error and massive help from stackoverflow managed to get it to work. I have used underscorejs to perform the string to byte array conversion as follows

output.write(_.map(query.split(''), function(c) {return c.charCodeAt(0)}));
Will retrace my tracks to learn what ensued in this quest.
0 x
ebasetech v5

Skype: mateso08
Location: Kenya


Who is online

Users browsing this forum: No registered users and 19 guests