Question

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!

Was it helpful?

Solution

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)

OTHER TIPS

What I did was something like this.

@app.after_request
def redirect_to_signin(response):
    if response.status_code == 401:
        return redirect(APP_HOST + '/auth/signin?next=' + request.url)

Then whenever a user can't be authenticated it just redirects them to the signin page and then exactly back to where they were. Great if you have different host names (i.e. app.website.com & website.com). See other request url fields in this SO answer

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top