Flask/Werkzeug, how to return previous page after login
I think standard practice is to append the URL to which the user needs to be redirected after a successful login to the end of the login URL's querystring.
You'd change your decorator to something like this (with redundancies in your decorator function also removed):
def logged_in(f): @wraps(f) def decorated_function(*args, **kwargs): if session.get('logged_in') is not None: return f(*args, **kwargs) else: flash('Please log in first...', 'error') next_url = get_current_url() # However you do this in Flask login_url = '%s?next=%s' % (url_for('login'), next_url) return redirect(login_url) return decorated_function
You'll have to substitute something for get_current_url()
, because I don't know how that's done in Flask.
Then, in your login handler, when the user successfully logs in, you check to see if there's a next
parameter in the request and, if so, you redirect them to that URL. Otherwise, you redirect them to some default URL (usually /
, I guess).
You could use a query string to keep the file info intact over a click or two. One of the nice things about url_for
is how it passes unknown parameters as query strings. So without changing your registration page too much you could do something like this:
def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if g.user is None: return redirect(url_for('register', wantsurl = request.path)) return f(*args, **kwargs) return decorated_function
Here wantsurl
will keep track of the url the user landed on. If an unregistered user goes to /download/some/file.txt
, login_required
will send you to /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt
Then you add a couple of lines to your registration function:
@app.route('/register', methods=['GET', 'POST'])def register(): if request.method == 'GET': if 'wantsurl' in request.args: qs = request.args['wantsurl'] return render_template('register.html', wantsurl=qs) if request.method == 'POST': if 'wantsurl' in request.form and everything_else_ok: return redirect(request.form['wantsurl'])
That would automatically redirect to the download on successful registration, provided you have something in the form called 'wantsurl' with the value of qs
, or you could have your form submit with a query string; that could just be a little if-else in the template.