Flask Snippets

Snippets are unofficial and unmaintained.

This is an archived view of user-submitted snippets. Despite being hosted on the Flask site, they are not official. No Flask maintainer has curated or checked the snippets for security, correctness, or design.

Secure Back Redirects with WTForms

Posted by Armin Ronacher on 2011-07-28 @ 11:47 and filed in Forms

With Flask-WTF it's easy to build a base form that handles automatic redirects to the previous page for you. This extends the Secure back redirect snippet for Flask-WTF.

from urlparse import urlparse, urljoin
from flask import request, url_for, redirect
from flaskext.wtf import Form, TextField, HiddenField


def is_safe_url(target):
    ref_url = urlparse(request.host_url)
    test_url = urlparse(urljoin(request.host_url, target))
    return test_url.scheme in ('http', 'https') and \
           ref_url.netloc == test_url.netloc


def get_redirect_target():
    for target in request.args.get('next'), request.referrer:
        if not target:
            continue
        if is_safe_url(target):
            return target


class RedirectForm(Form):
    next = HiddenField()

    def __init__(self, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)
        if not self.next.data:
            self.next.data = get_redirect_target() or ''

    def redirect(self, endpoint='index', **values):
        if is_safe_url(self.next.data):
            return redirect(self.next.data)
        target = get_redirect_target()
        return redirect(target or url_for(endpoint, **values))

Example form and view:

class LoginForm(RedirectForm):
    username = TextField('Username')
    password = TextField('Password')

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        # do something with the form data here
        return form.redirect('index')
    return render_template('login.html', form=form)

This snippet by Armin Ronacher can be used freely for anything you like. Consider it public domain.

Comments