【问题标题】:Conflict between captcha and CSRF验证码和 CSRF 之间的冲突
【发布时间】:2018-11-07 10:14:06
【问题描述】:

对于我的登录页面,我启用了验证码,用户必须输入图像中显示的 4 位数字。我为此使用了flask-session-captcha 模块。我完全按照说明中的步骤进行操作。

在同一个登录页面中,我还有一个隐藏的 CSRF 令牌。

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>

当我在本地环境(我的笔记本电脑)中开发和测试它时它工作正常,但当我在测试服务器中测试它时它不起作用。它会给出诸如“CSRF 令牌不匹配”之类的错误。或“无效验证码”(即使我回答正确)或有时“缺少 CSRF 令牌”。

我已经尝试了很多东西,比如为那个特定的登录页面使用装饰器@csrf_exempt。我还添加了这个:

@app.after_request
def apply_caching(response):
    response.headers["X-Frame-Options"] = "SAMEORIGIN"
    response.headers["Cache-Control"] = "public, max-age=0, no-cache, no-store, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "0"
    return response

但似乎没有任何效果。这真的让我很困惑,为什么它可以在本地而不是在测试服务器上工作。我试图不在登录页面中使用 csrf_token() ,但它给了我丢失 csrf 令牌的错误。使用 Google ReCaptcha 不是一种选择,因为用户不想使用它。

不知道是不是因为captcha token和csrf token冲突?

【问题讨论】:

    标签: python flask csrf captcha


    【解决方案1】:

    你可以试试flask_recaptcha吗?

    以下是最小化的示例。

    #app/__init__.py
    from flask_recaptcha import ReCaptcha
    recaptcha = ReCaptcha(app=app)
    
    #app/views/your_view.py
    @app.route('/a_view_for_demo/', methods=['GET', 'POST'])
    def a_view_for_demo():
        a_form = AForm()
        if a_form.validate_on_submit() and recaptcha.verify():
            # do your thing after validation.
    
        return render_template('a_template.html', a_form=a_form)
    
    #app_config
    RECAPTCHA_ENABLED=True
    RECAPTCHA_SITE_KEY="get this key from Google"
    RECAPTCHA_SECRET_KEY="get this key from Google"
    
    # a_template.html
    
    <form .....>
       {{ a_form.csrf_token }}
       {{ recaptcha }}
    </form>
    

    【讨论】:

    • 我之前尝试过,但就像我在帖子中提到的那样,用户不希望我使用 google recaptcha。
    猜你喜欢
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多