Created
March 16, 2012 08:42
-
-
Save fanzeyi/2049177 to your computer and use it in GitHub Desktop.
test for reCAPTCHA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import logging | |
import urllib | |
from tornado.auth import httpclient | |
class RecaptchaMixin(object): | |
""" | |
Example usage:: | |
class SignupHandler(BaseHandler, RecaptchaMixin): | |
def get(self): | |
if self.current_user: | |
return self.redirect('/') | |
form = SignupForm() | |
recaptcha = self.recaptcha_render() | |
return self.render('auth/signup.html', form=form, recaptcha=recaptcha) | |
@asynchronous | |
def post(self): | |
form = SignupForm(self.request.arguments) | |
if form.validate(): | |
user = form.save() | |
user.signup_ip = user.signin_ip = self.request.remote_ip | |
self.recaptcha_validate(self.async_callback(self._on_validate, user)) | |
return | |
recaptcha = self.recaptcha_render() | |
html = self.render_string('auth/signup.html', form=form, recaptcha=recaptcha) | |
self.write(html) | |
self.finish() | |
def _on_validate(self, user, response): | |
if not response: | |
form = SignupForm(self.request.arguments) | |
recaptcha = self.recaptcha_render() | |
html = self.render_string('auth/signup.html', form=form, recaptcha=recaptcha) | |
self.write(html) | |
self.finish() | |
return | |
self.db.add(user) | |
self.db.commit() | |
self.set_secure_cookie('user', user.email) | |
return self.redirect('/') | |
""" | |
RECAPTCHA_VERIFY_URL = "http://www.google.com/recaptcha/api/verify" | |
def recaptcha_render(self): | |
token = self._recaptcha_token() | |
html = u'<div id="recaptcha_div"></div>' | |
html += u'<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>' | |
s = u'<script type="text/javascript">Recaptcha.create("%(key)s", "recaptcha_div", {theme: "%(theme)s",callback: Recaptcha.focus_response_field});</script>' | |
html += s % token | |
return html | |
def recaptcha_validate(self, callback): | |
token = self._recaptcha_token() | |
challenge = self.get_argument('recaptcha_challenge_field', None) | |
response = self.get_argument('recaptcha_response_field', None) | |
callback = self.async_callback(self._on_recaptcha_request, callback) | |
http = httpclient.AsyncHTTPClient() | |
post_args = { | |
'privatekey': token['secret'], | |
'remoteip': self.request.remote_ip, | |
'challenge': challenge, | |
'response': response | |
} | |
http.fetch(self.RECAPTCHA_VERIFY_URL, method="POST", | |
body=urllib.urlencode(post_args), callback=callback) | |
def _on_recaptcha_request(self, callback, response): | |
if response.error: | |
logging.warning("Error response %s fetching %s", response.error, | |
response.request.url) | |
callback(None) | |
return | |
verify, message = response.body.split() | |
if verify == 'true': | |
callback(response.body) | |
else: | |
logging.warning("Recaptcha verify failed %s", message) | |
callback(None) | |
def _recaptcha_token(self): | |
self.require_setting("recaptcha_public_key", "Recaptcha Public Key") | |
self.require_setting("recaptcha_private_key", "Recaptcha Private Key") | |
self.require_setting("recaptcha_theme", "Recaptcha Theme") | |
token = dict( | |
key=self.settings["recaptcha_public_key"], | |
secret=self.settings["recaptcha_private_key"], | |
theme=self.settings["recaptcha_theme"], | |
) | |
return token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# AUTHOR: Zeray Rice <[email protected]> | |
# FILE: test.py | |
# CREATED: 15:51:36 16/03/2012 | |
# MODIFIED: 16:24:43 16/03/2012 | |
from recaptcha import RecaptchaMixin | |
from tornado.web import asynchronous | |
from judge.base import BaseHandler | |
class TestHandler(BaseHandler, RecaptchaMixin): | |
def get(self): | |
self.write("""<form method="POST" action="">""") | |
self.write(self.xsrf_form_html()) | |
self.write(self.recaptcha_render()) | |
self.write("""<button type="submit">Submit</button>""") | |
self.write("""</form>""") | |
@asynchronous | |
def post(self): | |
self.recaptcha_validate(self.async_callback(self._on_validate)) | |
def _on_validate(self, response): | |
self.write("""<form method="POST" action="">""") | |
self.write(self.xsrf_form_html()) | |
self.write(self.recaptcha_render()) | |
self.write("""<button type="submit">Submit</button>""") | |
self.write("""</form>""") | |
response = self.get_argument('recaptcha_response_field', None) | |
self.write("\"" + response + "\" ") | |
if response: | |
self.write("success!") | |
self.finish() | |
return | |
self.write("failed.") | |
self.finish() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
self.recaptcha_validate(self.async_callback(self._on_validate))
可以直接写 self.recaptcha_validate(self._on_validate)