login_required decorator from flask_login not redirecting to previous page

Avi Das picture Avi Das · Apr 18, 2014 · Viewed 12.5k times · Source

I am using flask_login for login and logout for an app but the redirection back to the previous page does not seem to be working. I am using the flask.views and login_required as a decorator for views that require user login. However, when I try to access /path which requires login it redirects to /login and not /login?next=/path which means that request.get.args("next") is None.

I am using login required with flask views in my blueprint as follows:

from flask import Blueprint, render_template, request, redirect, url_for
from flask.views import MethodView
from models import Post
from flask.ext.mongoengine.wtf import model_form
from flask.ext.login import login_required

posts_app = Blueprint('posts_app', __name__, template_folder='templates', static_folder='static', static_url_path='/static')

class ListView(MethodView):
    decorators = [login_required]

    def get(self):
        posts = Post.objects.all()
        print posts
        return render_template('posts/list.html', posts=posts)

posts_app.add_url_rule('/', view_func=ListView.as_view('list'))

In a separate blueprint I am implementing Authentication:

from flask import Blueprint, render_template, request, current_app, flash, redirect, url_for
from forms import LoginForm, RegisterForm, ForgotForm
from libs.User import User
from flask.ext.login import login_user, login_required, logout_user, confirm_login
from app import login_manager, flask_bcrypt

auth_login = Blueprint('auth_login', __name__, template_folder='templates')

@auth_login.route('/login', methods=["GET", "POST"])
def login():

    if request.method == "POST" and "email" in request.form:
        email = request.form["email"]
        userObj = User()
        user = userObj.get_by_email_w_password(email)
        if user and user.is_active() and flask_bcrypt.check_password_hash(user.password, request.form["password"]):
            remember = request.form.get("remember", "no") == "yes"

            if login_user(user, remember=remember):
                flash("Logged In!")
                return redirect(request.args.get('next') or url_for('index'))
            else:
                flash("Unable to log you in")

    form = LoginForm(request.form)
    return render_template('forms/login.html', form=form)

Could anyone familiar with login required decorator offer some advice? Thanks!

Answer

Avi Das picture Avi Das · Apr 18, 2014

Found what what was going wrong. In my authentication Blueprint, I was overriding @login_manager.unauthorized_handler to be

@login_manager.unauthorized_handler
def unauthorized_callback():
    return redirect('/login')

whereas I really needed to do:

@login_manager.unauthorized_handler
def unauthorized_callback():
    return redirect('/login?next=' + request.path)