web2py本身带有的CAPTCHA 和reCAPTCHA验证功能,只要在auth.settings.captcha参数配置即可,但是这块是调用Google的reCAPTCHA服务,服务器和客户都必须能有梯子访问Google,这显然不适用,开启了reCAPTCHA就长这样:
我们自己改造一下,本地生成个简单的验证码,改造需要修改web2py框架源代码:
一、gluon下的tools.py
1、搜索"if session.auth_two_factor_user is None:"段落
源代码长这样:
if session.auth_two_factor_user is None:
if settings.remember_me_form:
extra_fields = [
Field('remember_me', 'boolean', default=False,
label=self.messages.label_remember_me)]
else:
extra_fields = []
改成如下,这里主要是为登录框增加一个额外的验证码输入字段:
if settings.remember_me_form: extra_fields = [Field('capcha_code', 'integer'), Field('remember_me', 'boolean', default=False,label=self.messages.label_remember_me)] else: extra_fields = [Field('capcha_code', 'integer')]
2、接着这段下面
上面改的地方,紧着下吗 有 if settings.login_form == self:这段的最最下面增加生产验证码的段落:
digit1 = random.randint(1, 9) digit2 = random.randint(1, 9) digit3 = random.randint(1, 9) captcha_string = str(digit1)+'x'+str(digit2)+'+'+str(digit3)+"=?" current.session.captcha_result = digit1 * digit2 + digit3 from PIL import Image,ImageDraw import base64 from io import BytesIO image = Image.new("RGB", (42,12), 0) draw = ImageDraw.Draw(image) draw.text((0, 0),captcha_string) image = image.resize((80, 30)) img_buffer = BytesIO() image.save(img_buffer, format='JPEG') current.session.captcha_pic = XML('<img src=data:image/jpeg;base64,'+ base64.b64encode(img_buffer.getvalue())+'>')
这一段里面还有个 if form.accepts()的提交后的判断,增加:
if form.vars.capcha_code != current.session.captcha_result: session.flash = '验证码不对' redirect(self.url(args=request.args, vars=request.get_vars), client_side=settings.client_side)
二、修改default下的user.html
增加一段js,页面一加载就把验证码打出来:
<script> window.onload = function(){ $("#auth_user_capcha_code__label").html("请计算 : {{=current.session.captcha_pic}}"); } </script>
三、最后效果如下:
如果还要增加什么更复杂的验证码的干扰线,背景噪点,防止被识别什么的,可继续再优化验证码图片生成部分的代码。