working recaptcha v2 integration for contact/ register pages - Cheers!

by: kingfitz, 9 years ago

Last edited: 9 years ago

Hey,

just wanted to let you and others know how easy it is to implement recaptcha v2 for your contact or register pages, right in your existing wtforms.  beats writing an email confirmation convoluted rats nest of functions and deters any bots.  just login to a gmail acct, go to recaptcha page, enter your site domain and corresponding keys as explained below.  Cheers.  


# init.py

from flask_wtf import Form, RecaptchaField
from wtforms import BooleanField, TextField, TextAreaField, PasswordField,
     SubmitField, validators
    
# recaptcha config
DEBUG = True
SECRET_KEY = 'random alphanumeric key of your choice'
RECAPTCHA_PUBLIC_KEY = 'your google recaptcha site key'
RECAPTCHA_PRIVATE_KEY = 'your google recaptcha secret key'

app.config.from_object(__name__)
app.secret_key = 'random alphanumeric key of your choice - not SECRET_KEY'

class RegisterForm(Form):
        username = TextField('Username', [validators.Length(min=5, max=20)])
        email = TextField('Email Address', [validators.Length(min=8, max=50), validators.Email()])
        password = PasswordField('Password', [validators.Length(min=6, max=20, message='Password must be at least 6 characters'),
            validators.Required(), validators.EqualTo('confirm', message='Passwords must match')])
        confirm = PasswordField('')
        accept_tos = BooleanField('By registering, I accept the <br> <a href="/termsofservice/"> Terms </a> and <a href="/privacy/"> Privacy </a> (date/goes/here)', [validators.Required()])
        recaptcha = RecaptchaField()
    
    
    @app.route('/register/', methods=["GET","POST"])
    def register_page():
        try:
            form = RegisterForm()
    
            if request.method == "POST" and form.validate():
                username  = form.username.data
                email = form.email.data
                password = sha256_crypt.encrypt((str(form.password.data)))
                c, conn = connection()
    
                x = c.execute("SELECT * FROM users WHERE username = (%s)",
                              (thwart(username)))
    
                if int(x) > 0:
                    flash("That username is already taken, please choose another.")
                    return render_template("register.html", form=form)
    
                else:
                    c.execute("INSERT INTO users (username, password, email, tracking) VALUES (%s, %s, %s, %s)",
                              (thwart(username), thwart(password), thwart(email), thwart("/dashboard/")))
                    
                    conn.commit()
                    flash("Thanks for registering!")
                    c.close()
                    conn.close()
                    gc.collect()
                    
                    session['logged_in'] = True
                    session['username'] = username
    
                    return redirect(url_for("dashboard"))
    
            return render_template("register.html", form=form)
    
        except Exception as e:
            return(str(e))
    
    
    #  HTML page w/ register form
    
                    {% from "_formhelpers.html" import render_field %}    
                        <form method=post action="/register/">
                                   {{ form.hidden_tag() }}

                <dl>
                    {{render_field(form.username)}}
                    {{render_field(form.email)}}
                    {{render_field(form.password)}}
                    {{render_field(form.confirm)}} <br>
                    {{render_field(form.accept_tos)}} <br>
                    
                                        <div class="g-recaptcha" data-sitekey="your google site key goes here"></div>
            {% for error in form.recaptcha.errors %}
                 {{ error }}
            {% endfor %}
        {{ form.recaptcha }}
        
                </dl>
    
    <br>    
                    <p><input type=submit value=Register!></p>
                        </form>
    
    
    
    # _formhelpers.html
    
    {% macro render_field(field) %}
    
        <dt> {{ field.label }}
      <dd> {{ field(**kwargs)|safe }}
        
        {% if field.errors %}
          <ul class="errors">
            {% for error in field.errors %}
                <li> {{ error }} </li>
            {% endfor %}
          </ul>
        {% endif %}
    
      </dd>
        
    {% endmacro%}
          
    
    
    
    
    
    # working contact page example with recaptcha
    
    class ContactForm(Form):
        name = TextField('Your Name', [validators.Length(min=5, max=25)])
        email = TextField('Your Email', [validators.Length(min=8, max=50), validators.Email()])
        subject = TextField('Subject', [validators.Length(min=5, max=25)])
        inquiry = TextAreaField('Your Inquiry', [validators.Length(min=25, max=500)])
        recaptcha = RecaptchaField()
        submit = SubmitField('Submit!')    
    @app.route('/contact/', methods=["GET","POST"])
    def contact():
        try:
            form = ContactForm()
    
            if request.method == "POST":
                if form.validate() == False:
                    flash('Invalid! All fields & valid email are required.')
                    return render_template('contact.html', form=form)
                else:
                    msg = Message(form.subject.data, sender='form.email.data', recipients=['siteowner@gmail.com'])
                    msg.body = """
                    From: %s %s n
                    %s n
                    %s
                    """ % (form.name.data, form.email.data, form.subject.data, form.inquiry.data)
                    mail.send(msg)
                    
                    flash('Thank you, your inquiry has been sent successfully! We will respond shortly.')
                    gc.collect()
                    return render_template('index.html')
                    
            elif request.method == 'GET':
                return render_template("contact.html", form=form)
    
        except Exception as e:
            return(str(e))  
    
    
    # contact page html form
    
    <form action="{{ url_for('contact') }}" method=post>
        {{ form.hidden_tag() }}
    
        {{ form.name.label }}
        {{ form.name }}
    <br><br>
        {{ form.email.label }}
        {{ form.email }}
    <br><br>
        {{ form.subject.label }}
        {{ form.subject }}
    <br><br>
        {{ form.inquiry.label }}
    <br> <br>
        {{ form.inquiry(cols="40", rows="12") }}
    <br><br>
            <div class="g-recaptcha" data-sitekey="your google recapthca site key goes here"></div>
            {% for error in form.recaptcha.errors %}
                 {{ error }}
            {% endfor %}
        {{ form.recaptcha }}
    
    <br><br>    
        {{ form.submit(class_="submitbg labelcolor") }}
      </form>





You must be logged in to post. Please login or register an account.



Awesome! I had no idea this was built in to Flask! Thanks for sharing this.

-Harrison 9 years ago

You must be logged in to post. Please login or register an account.