Python 在瓶子中实现简单验证码

Python 在瓶子中实现简单验证码,python,web,captcha,bottle,Python,Web,Captcha,Bottle,我试图理解使用python web框架实现简单验证码的最佳方法。到目前为止,我所发现的都是人们要求提供即插即用验证码库,或者“真正安全”的复杂生成图像验证码实现,这使得代码示例很难理解。我很想知道在诸如烧瓶/瓶子这样的框架中实现验证码的最基本功能的“最佳实践”是什么: 向用户表单发送特定且唯一的人类可解决问题 跟踪这些问题及其对每个用户的正确答案 在收到表单后,验证分配给该用户的问题是否有正确答案 这不需要是一个健壮的实现,例如,它可以简单到发送一个简单的算术问题,如3+2=?。在这一点上,

我试图理解使用python web框架实现简单验证码的最佳方法。到目前为止,我所发现的都是人们要求提供即插即用验证码库,或者“真正安全”的复杂生成图像验证码实现,这使得代码示例很难理解。我很想知道在诸如烧瓶/瓶子这样的框架中实现验证码的最基本功能的“最佳实践”是什么:

  • 向用户表单发送特定且唯一的人类可解决问题
  • 跟踪这些问题及其对每个用户的正确答案
  • 在收到表单后,验证分配给该用户的问题是否有正确答案
这不需要是一个健壮的实现,例如,它可以简单到发送一个简单的算术问题,如3+2=?。在这一点上,我还没有掌握如何正确地实现这一点的基本知识

到目前为止,我已经实现了一个只对文本有效的非常基本的验证码,虽然我说过我不需要它来安全地理解原理,但我目前的方法无法成为任何安全的方法

模板:

<form action='/form' method='post'>
    {{ints[0]}} + {{ints[1]}}
    <input name='answer' value='{{ints[0] + ints[1]}}' type='hidden'>
    <input type='text' name='captcha'>
    <input type='submit' value='Submit'>
</form>
from bottle import default_app, route, template, post, request
import random


@route('/')
def test_display():
    ints = random.randint(0,9),random.randint(0,9)
    formhtml = template("temp", ints=ints)

    return formhtml

@route('/form', method='POST')
def print_form():
    value = request.forms.get('answer')
    if value != request.forms.get('captcha'):
        return 'Wrong.'
    else:
        return 'Correct.'

application = default_app()
我只是将每个生成的验证码的答案存储在用户表单的隐藏输入字段中。这可以绕过任何服务器端存储,但我直觉地知道,在客户端上存储问题的确切解决方案完全违背了验证码的目的。所以这不行

我需要的是某种服务器端会话存储,用于任何用户获取带有表单的页面,我需要以某种方式跟踪它,以便当他们发布表单时,服务器知道是谁发布了表单。因为框架是如此抽象,教程也不是很好地解释基本思想,我真的没有很好地掌握我可以做什么,或者我可以使用什么工具来实现这一点


瓶子甚至可能不容易完成这项任务(尽管我对此表示怀疑),因此,如果有更简单的python解决方案,我们欢迎您提出建议

无需与用户进行任何会话即可完成此操作。只需输入答案的哈希值

类似于散列(答案+当前时间)。当你检查答案时,请检查时间是否是最近的,你是否可以离开

@route('/form', method='POST')
def print_form():
    value = request.forms.get('answer')
    time_given_by_server =  request.forms.get('time_given_by_server')#also hidden

    captcha = hashlib.sha1("%s%s"% (request.forms.get('captcha'), time_give_by_server)).hexdigest()
    if value != catcha or time.time()-time_given_by_server > (60*5):#5 mintues is ok i guess...
        return 'Wrong.'
    else:
        return 'Correct.'

当然,您必须在测试显示中使用散列等方式准备“答案”…

我将基本上使用您在这里向我展示的内容。时间门很有趣,虽然我不确定如果表单超过5分钟,你会拒绝它,这是什么意思。我们难道不想检查一下,是否已经过了一些最短时间来过滤即时填写表单的机器人,即使答案是正确的吗?@MylesGallagher-最短时间很好,但五分钟的限制是针对回复攻击的,我明白了,以防止重复发送同一表单。