Search code examples
flaskpycharmflask-loginflask-mongoengine

Flask-login redirecting back to login page


I am writing a simple flask app using flask-login and flask-mongoengine, everything was working fine until I updated all of the python plugins that I need for the project. Now flask won't log me in. When I login and the form is validated, it returns me to the login page, with the url: http://localhost:5000/auth/login?next=%2Findex ... I think the %2F might have something to do with the issue.

Here is my login view:

@bp.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.objects(username__exact=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash(_('Invalid username or password'))
            return redirect(url_for('auth.login'))
        login_user(user, remember=form.remember_me.data)
        next_page = request.args.get('next')
        if not next_page or url_parse(next_page).netloc != '':
            next_page = url_for('main.index')
        return redirect(next_page)
    return render_template('auth/login.html', title=_('Sign In'), form=form)

I'm using WTForms and I can confirm that the form action=""

This is adapted from the flask megatutorial, but I'm using MongoDB.


Solution

  • Problem solved!

    When I was converting the app from using SQL to MongoDB, I incorrectly made the load_user function like:

    @login.user_loader
    def load_user(username):
        return User.objects(username__exact=username).first()
    

    But in reality the load_user function needs to accept the id field as an interface, so the function should look like:

    @login.user_loader
    def load_user(id):
        return User.objects.get(id=id)