KnugiHK/flask-hcaptcha

How to detect verified captcha on template file?

Closed this issue · 15 comments

I need to check if the captcha is verified or not and enable/disable the submit button. Is this currently possible?

Yes. You can use the data-callback or callback configuration. Learn more on https://docs.hcaptcha.com/configuration#hcaptcha-container-configuration.

Got it. Thanks @KnugiHK.

@KnugiHK apologies for my ignorance, but I'm struggling with adding data-callback to {{ hcaptcha }} in my jinja variable. Or do I need to set it elsewhere?

@KnugiHK apologies for my ignorance, but I'm struggling with adding data-callback to {{ hcaptcha }} in my jinja variable. Or do I need to set it elsewhere?

Hi! In the current release, {{ hcaptcha }} does not support the any custom data attribute. However, I've just added support for optional data attributes in commit 0957eef. To use this feature, pass the attribute without the data- prefix when initializing the plugin. For example:

hcaptcha = hCaptcha(app, callback="done") # Where done is a JS function.

This will result in:

<div class="h-captcha" data-sitekey="20000000-ffff-ffff-ffff-000000000002" data-theme="light" data-callback="done">

You can try this in dev branch.

from flask import Flask, render_template_string, request
from flask_hcaptcha import hCaptcha

app = Flask(__name__)

# Replace these with your actual hCaptcha site key and secret key
app.config['HCAPTCHA_SITE_KEY'] = '20000000-ffff-ffff-ffff-000000000002'
app.config['HCAPTCHA_SECRET_KEY'] = '0x0000000000000000000000000000000000000000'

# Initialize hCaptcha
hcaptcha = hCaptcha(app, callback="done1")

# Simple in-memory form submission storage (for demonstration)
submissions = []

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # Verify hCaptcha
        if not hcaptcha.verify():
            return render_template_string(HTML_FORM, error="hCaptcha verification failed. Please try again.")
        
        # If hCaptcha verification is successful, process form data
        name = request.form['name']
        submissions.append({'name': name})
        return render_template_string(HTML_FORM, success="Form submitted successfully!", submissions=submissions)

    return render_template_string(HTML_FORM)

# Simple HTML form with hCaptcha widget
HTML_FORM = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask hCaptcha Example</title>
</head>
<body>
    <h1>Submit Your Information</h1>

    {% if error %}
    <div style="color: red;">{{ error }}</div>
    {% endif %}
    {% if success %}
    <div style="color: green;">{{ success }}</div>
    {% endif %}
    <script>
        function done1(){console.log("done1")}
        function done2(){console.log("done2")}
    </script>

    <form method="POST">
        <label for="name">Name:</label><br>
        <input type="text" id="name" name="name" required><br><br>
        {{ hcaptcha }}  <!-- hCaptcha widget -->
        {{ hcaptcha_with(callback='done2') }}  <!-- hCaptcha widget -->

        <br><br>
        <button type="submit">Submit</button>
    </form>

    <h2>Submissions</h2>
    <ul>
    {% for submission in submissions %}
        <li>{{ submission.name }} - {{ submission.email }}</li>
    {% endfor %}
    </ul>
</body>
</html>
'''

if __name__ == '__main__':
    app.run(debug=True)

Yes, amazing thank you!!

To clarify, can multiple data attributes be set in this way for the same hcaptcha?

To clarify, can multiple data attributes be set in this way for the same hcaptcha?

Yes. For example if you want data-size="normal":

hcaptcha = hCaptcha(app, callback="done", size="normal")

Although I haven't test it, it should work. If not, let me know!

@KnugiHK confirmed it works to set data-callback and data-size together! It's interesting to set these attributes on initialization because it means all hcaptchas on my site need to have the same configuration. It's not a problem for me, but there's only one page for which I need data-callback and the rest log [hCaptcha] Callback 'captchaPassed' is not defined to the console. I realize it's a simple fix, just an observation.

@KnugiHK confirmed it works to set data-callback and data-size together! It's interesting to set these attributes on initialization because it means all hcaptchas on my site need to have the same configuration. It's not a problem for me, but there's only one page for which I need data-callback and the rest log [hCaptcha] Callback 'captchaPassed' is not defined to the console. I realize it's a simple fix, just an observation.

Good observation! I added another function for that: hcaptcha_with. See my updated example above.

Awesome! So can {{ hcaptcha_with(callback="done2" }} be used if the callback parameter is not set on initialization? Is it safe to assume {{ hcaptcha }} does not need to be included alongside hcaptcha_with as in the example above?

Awesome! So can {{ hcaptcha_with(callback="done2" }} be used if the callback parameter is not set on initialization? Is it safe to assume {{ hcaptcha }} does not need to be included alongside hcaptcha_with as in the example above?

Yes. You can use either {{ hcaptcha_with() }} or {{ hcaptcha }} to set a default widget.

{{ hcaptcha_with() }} and {{ hcaptcha }} do not depend on each other. The example is just to show there are two possible ways to do so now.

That’s perfect. Thank you for supporting these use cases!

Released in 0.7.0.

Curious about how releases work. Your Readme and pip indicate the latest version is 0.6.0, but I see that the latest download available is 0.7.0. Is there a review process or some other reason for the difference?