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

| |
[Django]Easy Captcha的再思考 软件技术
lhwork 发表于 2007/1/15 10:55:01 |
头太晕在我的blog中留言说我的实现方法无法解决第一次手工输入,以后一直使用这个正确的值来攻击的问题,我想一想的确如此。看来完全依赖客户端是不够的,还是要在后台做一些工作。为了让后台的工作尽量少,我不想单独建表来象session一样的处理。我也不想去产生一个id与word进行对应,因为生成id是一个问题,为了保证不重复,要通过循环来实现,感觉不好。于是我想不如将key的生成时间也写在key中,这样在后台我只要判断是否超时,就可以让这个key失败。但这也只是解决了key的长期有效的问题,无法解决在短时间内攻击的问题。那么我想可以利用cache的机制,一旦key中的word验证有效,并且没有失效,那么先在cache中查找是否存在,如果不存在则说明没有验证过,然后在cache中设置一个word值既可。这样,下次再次校验相同的word时,因为cache中已经有了这个值,所以验证失效。我想这样应该可以解决问题。改动的代码如下:
#django bindingfrom django.conf import settingsfrom django.core.cache import cacheimport base64import md5import time
TIMEOUT = 5*60
def create_key(): word = valid_obj().word date = time.strftime("%Y%m%d%H%M%S") d = md5.new(word + date + settings.SECRET_KEY).hexdigest() w = base64.standard_b64encode(word) return w + date + d
def get_word(key): try: d = key[-32:] date = key[-46:-32] w = key[:len(key)-46] #judge the time t = time.mktime(time.strptime(date, "%Y%m%d%H%M%S")) if 0 <= time.time() - t <= TIMEOUT: word = base64.standard_b64decode(w) nd = md5.new(word + date + settings.SECRET_KEY).hexdigest() if nd == d: return word except: import traceback traceback.print_exc() pass return False
def valid_key(key, word): k = get_word(key) if k: flag = k == word if flag: #check if the cache has the key, if has the key should be invalid if cache.get(word): return False else: #set to cache cache.set(word, 1, TIMEOUT) return True else: return False
完整的代码可以在 SharePlat 中找到。utils/validcode.py
update: 将date也作为生成md5的一部分。 |
|
|