How do I go about fixing a login system using flask_login and mongoengine?

42 Views Asked by At

I am working with flask, flask_login and mongoengine and am having an issue when testing the login system I attempted to write. When I ran my code originally I got an error stating it could not resolve username. This prompted me (after trying a whole array of variable names to no different end result) to try again from scratch in a fresh project (code below). I now do not get any error messages but when I test the login setup, it fails to login and just removes any text in the password box when pressing the submit button. How do I fix this so the login works?

Entry in Mongodb that is being used as the test case, Email is the username, Password is the password

app.py (entries for secret_key, db, host and port were replaced with garbage data for this post, the database is hosted online)

#imports
from flask import *
from flask_wtf import *
from wtforms import *
from wtforms.validators import *
from flask_login import *
from app import *
from flask_mongoengine import *
from werkzeug.security import *

app = Flask(__name__)

app.config.from_mapping(
    SECRET_KEY='secret key here', 
    MONGODB_SETTINGS={
        'db': 'db here', 
        'host': 'host here', 
        'port': port here
    }
)

db = MongoEngine()
login_manager = LoginManager()
login_manager.login_view = '.homepage'

db.init_app(app)
login_manager.init_app(app)

@login_manager.user_loader 
def load_user(userID):
    return Test2.objects(user=userID).first()

class Test2(UserMixin, db.Document):
    UserID = db.StringField()
    FirstName = db.StringField()
    LastName = db.StringField()
    Birthday = db.StringField()
    Email = db.StringField()
    Password = db.StringField()
    AccountType = db.StringField()
    Address = db.StringField()
    Phone = db.StringField()

    def check_password(self, password):
        return check_password_hash(self.Password, password)


class LoginForm(FlaskForm):
    username = StringField("email", validators=[InputRequired()])
    password = PasswordField("password", validators=[InputRequired()])


@app.route("/", methods = ["get", "post"])
def homepage():
    form = LoginForm(request.form)
    if form.validate_on_submit():
        user = Test2.objects(Email=form.username.data).first()
        if user and user.check_password(form.password.data):
            login_user(user)
            next_url = request.args.get('next')
            return redirect(next_url or url_for('.loggedin'))
    return render_template('/homepage.html', **locals())

if __name__ == "__main__":
    app.run(debug = True, port = 5000)

homepage.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>login</title>
</head>
  <body>

  <form method = "Post" action = "{{ url_for('homepage') }}">
      {{ form.csrf_token }}
      {{ form.username.label }}
      {{ form.username }}
      {{ form.password.label }}
      {{ form.password }}

      <input type = "submit" value = "submit">
    </form>

  </body>
</html>

loggedin.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>login</title>
</head>
  <body>

    <p>logged in</p>

  </body>
</html>
1

There are 1 best solutions below

0
x... On

I realized I forgot to encrypt the password on the second attempt, I was checking encrypted text against a plain text password in the database. After that the answer was adjusting the variable in:

@login_manager.user_loader 
def load_user(userID):
    return Test2.objects(user=userID).first()

changing user=userID to Email=userID. I at least hope this helps somebody in the future.