为micolog添加图形验证码

micolog带的算法验证码似乎太弱了,容易引来垃圾评论。我把它改成了图形验证码,并加入了session机制。图形验证码的实现来自SDBlog,使用的是pngcanvas库绘制;session实现来自gmemsess库,基于memcache。

原理是访客访问/checkimg/获得生成的图形验证码,同时服务器使用session保存验证码值,并在处理提交评论表单时检查。

先测试一下效果,代码以后再整理。

部分代码如下:

safecode.py,gmemsess.py,pngcanvas.py放到app目录

blog.py添加CheckImg类,并在主函数添加路径映射,用于生成验证码图片:

('/checkimg/', CheckImg),
from app.safecode import Image
from app.gmemsess import Session

class CheckImg(BaseRequestHandler):
    def get(self):
        img = Image()
        imgdata = img.create()
        sess=Session(self,timeout=180)
        if not sess.is_new():
            sess.invalidate()
            sess=Session(self,timeout=180)
        sess['code']=img.text
        sess.save()
        self.response.headers['Content-Type'] = "image/png"
        self.response.out.write(imgdata)

Post_comment主要修改如下,验证输入的验证码和session中的是否一致:

        sess=Session(self,timeout=180)
        if not self.is_login:
            if not (self.request.cookies.get('comment_user', '')):
                try:
                    logging.info(checkret)
                    logging.info(sess['code'])
                    if sess.is_new() or (int(checkret) != sess['code']):
                        sess.invalidate()
                        if useajax:
                            self.write(simplejson.dumps((False,-102,('Your check code is invalid .'))))
                        else:
                            self.error(-102,('Your check code is invalid .'))
                        return
                   
                except:
                    sess.invalidate()
                    if useajax:
                        self.write(simplejson.dumps((False,-102,('Your check code is invalid .'))))
                    else:
                        self.error(-102,('Your check code is invalid .'))
                    return
        sess.invalidate()

为了使验证码显示(默认首次访问检查验证码),可以点击这里清除cookie

转载请注明:来自vvonder's blog
本文地址:http://vvonderblog.appspot.com/2009/11/25/add-micolog-image-checkcode.html



37 条评论

我要留言
  • 1 F

    云在天边 发表于 2009-11-25 at 21:27 回复 引用

    为什么第一次不能自动显示图像呢,非要手动点了才能出现验证码吗?
  • 2 F

    vvonder 发表于 2009-11-25 at 21:37 回复 引用

    @云在天边-53005:
    我这样设定的,因为验证码有过期时间(3分钟),而且不是每个访客都要留言,还可以节省流量
  • 3 F

    云在天边 发表于 2009-11-25 at 21:42 回复 引用

    引用vvonder
    @云在天边-53005:
    我这样设定的,因为验证码有过期时间(3分钟),而且不是每个访客都要留言,还可以节省流量

    哦,我刚下了你的代码,有时间我也去弄弄
  • 4 F

    云在天边 发表于 2009-11-25 at 23:23 回复 引用

    有点问题啊,如果一篇文章没有评论的话,评论分页的下一页仍然有效,点击后就会出现404找不到页面了
  • 5 F

    vvonder 发表于 2009-11-26 at 12:14 回复 引用

    @云在天边-54005:
    inove主题可以参照5style主题改,comments.html文件里加入个if else即可。等下我再发一个主题调整过的版本。
  • 6 F

    yanpeng 发表于 2009-11-26 at 15:05 回复 引用

    这个不错哈,可是我咋没看见你blog上面用它...
  • 7 F

    云在天边 发表于 2009-11-26 at 18:07 回复 引用

    @yanpeng-55002:
    你是怎么留言的呢?出来的就是图形啊
  • 8 F

    vvonder 发表于 2009-11-26 at 18:11 回复 引用

    @yanpeng-55002:
    默认只验证一次,就记住用户身份(不过ie好像无效),如果效果不好再改为每次验证。点上面的清除cookie后刷新可以看到验证码。
  • 9 F

    ooaixt 发表于 2009-11-26 at 23:52 回复 引用

    如果垃圾留言的先来留言一次通过呢?
  • 10 F

    vvonder 发表于 2009-11-27 at 12:31 回复 引用

    @ooaixt-55004:
    人肉很难防的,这个主要是防机器,当然带上cookie是可以绕过的。为了用户体验,这里暂时不搞太高强度。
  • 11 F

    hysia 发表于 2009-11-27 at 17:02 回复 引用

    我最近还添加了 多用户写作.管理BLOG,代码高亮和 LightBox . 文件上传模块也重写了,还增加了文件备注和上传用户.
  • 12 F

    yishanhe 发表于 2009-11-28 at 00:33 回复 引用

    你好,我是翻墙登陆你的博客的,我的博客也遇到同样的问题,是被封了么?想知道你的解决办法
  • 13 F

    vvonder 发表于 2009-11-28 at 09:44 回复 引用

    @yishanhe-56002:
    appspot没有被封啊,如果有自己的域名的话可以找ghs的反向代理绑定,看看www.you8g.com还有没有名额去要一个。
  • 14 F

    蓝冰 发表于 2009-11-28 at 11:13 回复 引用

    这是个好东西啊
  • 15 F

    zhy 发表于 2009-12-09 at 15:15 回复 引用

    偶顶着大墙来看你啦
  • 16 F

    Shen 发表于 2010-02-07 at 17:48 回复 引用

    好东西啊 !!!
  • 17 F

    cho 发表于 2010-02-13 at 22:21 回复 引用

    真复杂……~

    我现在改模板时都遇到验证码的麻烦了,现在验证码形同虚设,无需填写也能发表评论了,有时间帮帮忙行吗?

    主题:http://www.cho.org.ru/media/agdibG9nc3Rocg0LEgVNZWRpYRiJ0AIM/journalist.zip
  • 18 F

    知秋 发表于 2010-04-14 at 20:50 回复 引用

    这个主题很漂亮,但升级Micolog 0.7RC1以后无法管理登陆了。请问该怎么改文件?
  • 19 F

    vvonder 发表于 2010-04-20 at 14:31 回复 引用

    @知秋-87001:
    这段时间比较忙,博客和主题也好久没更新了,有时间我再更新一个micolog0.7的主题
  • 20 F

    bezetek 发表于 2010-04-20 at 20:29 回复 引用

    赶紧发布0,7的主题,我刚升级了试试,有点问题,现在主要是验证码的问题,你的网站现在就没有显示验证码啊....
  • 21 F

    news updates 发表于 2010-04-24 at 20:33 回复 引用

    nnice blog man !!!
  • 22 F

    chenzaichun 发表于 2010-05-08 at 12:52 回复 引用

    引用bezetek
    赶紧发布0,7的主题,我刚升级了试试,有点问题,现在主要是验证码的问题,你的网站现在就没有显示验证码啊....


    默认官方主题没有验证码了!
  • 23 F

    Leyond 发表于 2010-05-09 at 14:20 回复 引用

    真的非常不错,高手啊
  • 24 F

    Leyond 发表于 2010-05-09 at 15:13 回复 引用

    非常感谢,用上了Smile

  • 25 F

    Leyond 发表于 2010-05-10 at 22:59 回复 引用

    Big grin发现从micolog下载这个主题包跟你博客不一样,那个验证码显示方式啊
  • 26 F

    vvonder 发表于 2010-05-11 at 19:30 回复 引用

    @Leyond-127001:
    我的博客还没更新到0.7,那个主题是for 0.7的
  • 27 F

    Crisiel 发表于 2010-05-21 at 23:53 回复 引用

    请问这个图形验证码的完整代码可以发给我吗?
  • 28 F

    vvonder 发表于 2010-05-23 at 16:55 回复 引用

    @Crisiel-134001:

    这里下载最新版的micolog,里面有文中提到的3个py库文件和实现
  • 29 F

    Crisiel 发表于 2010-05-23 at 20:24 回复 引用

    @vvonder-136001:
    Thanks~
  • 30 F

    yi_tian 发表于 2010-05-31 at 12:53 回复 引用

    学习了
  • 31 F

    enki 发表于 2010-07-13 at 12:36 回复 引用

    很好用的博客,如果我切换到gap上,就用你的程序 哈
  • 32 F

    美国优洛 发表于 2010-07-19 at 18:27 回复 引用

    不会用啊。。
  • 33 F

    jerry 发表于 2010-09-27 at 18:45 回复 引用

  • 34 F

    gg 发表于 2010-10-15 at 20:20 回复 引用

    testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest

  • 35 F

    wefgew 发表于 2010-10-22 at 18:27 回复 引用

    greg
  • 36 F

    xhliu 发表于 2011-04-08 at 22:33 回复 引用

    为什么的我的引用按钮无效呢?回复却是好的,代码如下,帮忙看看:
    链接

    回复引用


    js部分:
    function backcomment(name,id){
    backdb=document.getElementById('comment');
    backdb.value+="@"+name+"-"+id+":\n";
    return true;
    }
    function quote(name,id){
    var quoteMsg=document.getElementById(id).innerHTML;
    document.getElementById("comment").value+='引用'+name+'
    '+quoteMsg+'
    \n';
    return true;
    }
  • 37 F

    xhliu 发表于 2011-04-08 at 22:43 回复 引用

    晕,代码竟然贴不上,再试试:
    链接:
    <a onclick="return backcomment('{{comment.author}}','{{comment.key.id}}')" href="#commentform" title="@{{comment.author}}-{{comment.key.id}}:">回复</a><a onclick="return quote('{{comment.author}}','commenttext-{{comment.key.id}}')" href="#commentform">引用</a>

    js:
    function backcomment(name,id){
    backdb=document.getElementById('comment');
    backdb.value+="@"+name+"-"+id+":\n";
    return true;
    }
    function quote(name,id){
    var quoteMsg=document.getElementById(id).innerHTML;
    document.getElementById("comment").value+='引用'+name+'<blockquote>'+quoteMsg+'</blockquote>\n';
    return true;
    }