Tuesday, May 22, 2012

How to implement user_loader in Flask-Login (flask site authentication)

I am trying to use the Flask-Login extension for user authentication in python/flask, and I'm stuck on how to implement the @login_manager.user_loader callback function when retrieving a user account from a database (rather than from a dictionary of User objects provided within the source code itself, as shown by the Flask-Login example).



The documentation says I need to pass this function a User ID number, and return the corresponding User object. Something to this effect:



@login_manager.user_loader
def load_user(userid):
return User.get(userid)


But because this function (apparently) must reside outside the scope of the /login route, this doesn't work when you need to check the user account against a database at the time that the /login form data is received:



@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST" and "username" in request.form:
username = request.form["username"]

# query MongoDB for the existence of the entered username:
database_result = users_collection.find_one({ 'username' : username})
User = UserClass(username, testdb['userid'], active=True)

if username == database_result['username']:
login_user(User)
return url_for("index")
else:
flash("Username not found.")
else:
flash("Error logging in.")
return render_template("login.html")


This is a rough excerpt. But for our purposes, let's say this code would fail at the callback function, and generate the error: "NameError: global name 'User' is not defined".



How do I correctly pass a User object to the user_loader callback on the fly, when the User object only gets created within the /login route's scope after it's located in the database?



Thanks for any guidance. I hope I'm explaining this clearly enough. I've been reading and re-reading the Flask-Login documentation, and it seems simple, except when I try to pull user data from anything other than a pre-determined dictionary at the top of the python source file.





No comments:

Post a Comment