Indeed, there is no need to implement the reCaptcha-client plugin for python/Tornado. We can simply use the AsyncHTTPClient to directly communicate to the reCaptcha API.
Register a reCaptcha on Google. Get the:
- public key
- private key
The reference I followed is this:
Insert this script into template
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
The below one just to create the reCaptcha object
Recaptcha.create("your_public_key", "element_id", { theme: "red", callback: Recaptcha.focus_response_field } );
Upon calling, the above code will create an image and 2 input forms, namely "recaptcha_response_field" and "recaptcha_challenge_field". The challenge field is hidden and contains a string to identify the challenge on the Google server.
- Create an ajax to send these 2 inputs to your server.
At the server side:
recaptcha_challenge=self.get_argument('recaptcha_challenge','') recaptcha_response=self.get_argument('recaptcha_response','') recaptcha_http=tornado.httpclient.AsyncHTTPClient() recaptcha_priv_key='xxxxxxyyyyyyyyzzzzz' remote_addr=self.request.headers['X-Real-Ip'] recaptcha_req_data={ 'privatekey':recaptcha_priv_key, 'remoteip':remote_addr, 'challenge':recaptcha_challenge, 'response':recaptcha_response } recaptcha_req_body=urllib.urlencode(recaptcha_req_data) try: recaptcha_http.fetch('http://www.google.com/recaptcha/api/verify', self.callback, method='POST',body=recaptcha_req_body) #https://developers.google.com/recaptcha/docs/verify except tornado.httpclient.HTTPError,e: print 'Error:',e
- Because the my Tornado is under Nginx proxy, so from the Nginx proxy I added a header (X-Real-IP) to forward the client's IP to Tornadoes.
- The above code will send to Google's API and Google will return a response with 2 lines:
true
xxyyyyzzz
- In the self.callback, you can first split the response by "\n", to obtain true or false value.
- Then you can perform your subsequent operations.
- The above code will send to Google's API and Google will return a response with 2 lines:
true
xxyyyyzzz
- In the self.callback, you can first split the response by "\n", to obtain true or false value.
- Then you can perform your subsequent operations.