本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7593715
建立时间:2006年5月29日




[Django]Easy Captcha的实现
软件技术

lhwork 发表于 2007/1/15 10:53:57

前面的blog中我已经开始研究 pycaptcha 的实现机理,就是想实现一个简单的 captcha 的机制。那么在 session 学习中,我们也了解了 session 的机制与 pycaptcha 的机制差不多,但是我感觉很麻烦。 那么如何才简单呢?考查现有的 pycaptcha 实现,它是将客户端的识别信息与生成图片的文本进行对应,即一个id对应一系列的solution(文本串),前端只看到id,然后通过提交将id和看到的图片中的文本一起传到后台,然后后台处理需要根据id得到对应的solution,再比较solution与上传的文本是否一致。如果一致则成功,否则失败。那么需要在后台保存id与solution的关系,这也很麻烦。因此我想如果前端保存的id包含了生成的文本,那么只要在后台比较这个文本与用户输入的文本是否一致就行了。那么这个id需要足够安全才好。同时可以根据这个id生成相应的图片。因此从处理上可以这样: 首先生成模版,在模版中生成一个key,并将这个key保存到一个hidden字段中。然后再生成一个图片的链接,将key作为一个索引。在传到浏览器后,图片由另一个view方法来根据这个key,得到word,然后根据word来生成一个图片返回。然后用户根据图片的文字进行输入并提交,然后在后台相应的校验方法中,根据key得到word,再比较用户输入的是否相同就行了。 那么整个过程清楚了,下一步就是如何让key既包含word的信息,同时又不容易被伪造,因此我采用将word和SECRET_KEY连接在一起然后生成一个md5的摘要信息,然后再将word生成为base64编码,将这个编码与摘要信息合并成一个字段后就生成这个key了。 生成代码如: d = md5.new(word + settings.SECRET_KEY).hexdigest()w = base64.standard_b64encode(word)return w+d 那么如何根据key进行校验并得到word呢?代码如下: def get_key(key):    try:        d = key[-32:]        w = key[:len(key)-32]        word = base64.standard_b64decode(w)        nd = md5.new(word + settings.SECRET_KEY).hexdigest()        if nd == d:            return word    except:        pass    return False    def valid_key(key, word):    k = get_word(key)    if k:        return k == word    else:        return False get_key()是根据key进行校验,并得到对应的word值。valid_key()则调用get_key()来校验和得到word,然后再比较word与上传的文本。在get_key()中,因为生成的摘要串是定长的32位,因此后32位是摘要,前面自然是base64编码后的word了。但为了防止有人知道规则进行伪造,因此要对摘要信息进行验证。方法就是将得到的word再使用相同的方法生成摘要信息,然后比较两个摘要信息是否一致。如果一致说明key是正确的。然后返回得到的word,如果不成功则返回False。然后在valid_key()中,再比较word和上传的文本就可以了。 下面是一个template的例子: {% load utiltags %}<form method="post" action="/test/valid/"><p>校验码:<input type="text" name="word" value=""/>{% pycall utils.validcode.create_key() as key %} <img src="/test/image/{{ key }}/" align="absmiddle"/></p><p><input type="hidden" name="key" value="{{ key }}"/></p><p><input type="submit" value="提交"/></p></form> 这里我装入了 utiltags tag 模块。并且使用了我新开发的 pycall tag。这样生成一个key就很简单了: {% pycall utils.validcode.create_key() as key %} 可以看到,生成的key保存到了key变量中了。然后在img标签中要使用这个key,在hidden中要使用这个key。 为了根据img的key生成对应的图片,需要一个view来处理,代码为: def image(request, key):    k = valid_key(key)    if k:        w, img = get_image(k)        return HttpResponse(img, 'image/jpg') 这里使用了一个 get_iamge() 方法,根据指定的文本串来生成图片。但在生成前先要通过 valid_key() 来校验和得到word。 校验代码的简单示意为: def valid(request):    word = request.POST['word']    key = request.POST['key']    w = valid_key(key)    if w and w == word:        return HttpResponse('成功!')    else:        return HttpResponse('无效!') 先通过valid_key()对key进行校验并得到对应的word,然后与用户上传的word进行比较,然后给出回复。 在致处理如下,一些方法我使用了以前写的一些东西。


阅读全文(2097) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.320 second(s), page refreshed 144763649 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号