title: How to implement user_loader callback in Flask-Login
body: <p>I'm attempting to use Flask and the <a href="http://packages.python.org/Flask-Login" rel="noreferrer">Flask-Login</a> extension to implement user authentication in a Flask app. The goal is to pull user account information from a database and then log in a user, but I'm getting stuck; however, I've narrowed it down to a particular part of Flask-Login behavior.</p>
  
  <p>According to the <a href="http://packages.python.org/Flask-Login/#how-it-works" rel="noreferrer">Flask-Login documentation</a>, I need to create a user_loader "callback" function. The actual purpose and implementation of this function has had me confused for a few days now:</p>
  
  <blockquote>
    <p>You will need to provide a user_loader callback. This callback is used
    to reload the user object from the user ID stored in the session. It
    should take the Unicode ID of a user, and return the corresponding
    user object. For example:</p>
  
  <pre><code>@login_manager.user_loader
  def load_user(userid):
      return User.get(userid)
  </code></pre>
  </blockquote>
  
  <p>Now, say I want the user to enter a name and password into a form, check against a database, and log in the user. The database stuff works fine and is no problem for me. </p>
  
  <p>This 'callback' function wants to be passed a user ID #, and return the User object (the contents of which I'm loading from a database). But I don't really get what it's supposed to be checking/doing, since the user IDs are all pulled from the same place anyway. I can 'sort-of' get the callback to work, but it seems messy/hackish and it hits the database with every single resource that the browser requests. I really don't want to check my database in order to download favicon.ico with every page refresh, but flask-login seems like it's forcing this. </p>
  
  <p>If I don't check the database again, then I have no way to return a User object from this function. The User object/class gets created in the flask route for logging in, and is thus  out of scope of the callback.</p>
  
  <p>What I can't figure out is how to pass a User object into this callback function, without having to hit the database every single time. Or, otherwise figure out how to go about doing this in a more effective way. I must be missing something fundamental, but I've been staring at it for a few days now, throwing all kinds of functions and methods at it, and nothing is working out. </p>
  
  <p>Here are relevant snippets from my test code. The User class:</p>
  
  <pre><code>class UserClass(UserMixin):
       def __init__(self, name, id, active=True):
            self.name = name
            self.id = id
            self.active = active
  
       def is_active(self):
            return self.active
  </code></pre>
  
  <p>The function I made to return the user object to Flask-Login's user_loader callback function:</p>
  
  <pre><code>def check_db(userid):
  
       # query database (again), just so we can pass an object to the callback
       db_check = users_collection.find_one({ 'userid' : userid })
       UserObject = UserClass(db_check['username'], userid, active=True)
       if userObject.id == userid:
            return UserObject
       else:
            return None
  </code></pre>
  
  <p>The 'callback', which I don't totally understand (must return the User object, which gets created after pulling from database):</p>
  
  <pre><code>@login_manager.user_loader
  def load_user(id):
       return check_db(id)
  </code></pre>
  
  <p>The login route:</p>
  
  <pre><code>@app.route("/login", methods=["GET", "POST"])
  def login():
       if request.method == "POST" and "username" in request.form:
            username = request.form["username"]
  
            # check MongoDB for the existence of the entered username
            db_result = users_collection.find_one({ 'username' : username })
  
            result_id = int(db_result['userid'])
  
            # create User object/instance
            User = UserClass(db_result['username'], result_id, active=True)
  
            # if username entered matches database, log user in
            if username == db_result['username']:
                 # log user in, 
                 login_user(User)
                 return url_for("index"))
            else:
                 flash("Invalid username.")
        else:
             flash(u"Invalid login.")
        return render_template("login.html")
  </code></pre>
  
  <p>My code 'kinda' works, I can log in and out, but as I said, it must hit the database for absolutely everything, because I have to provide a User object to the callback function in a different namespace/scope from where the rest of the login action takes place. I'm pretty sure I'm doing it all wrong, but I can't figure out how.</p>
  
  <p>The example code provided by flask-login <a href="https://github.com/maxcountryman/flask-login/blob/master/example/login-example.py" rel="noreferrer">does it this way</a>, but this only works because it's pulling the User objects from a global hard-coded dictionary, not as in a real-world scenario like a database, where the DB must be checked and User objects created <em>after</em> the user enters their login credentials. And I can't seem to find any other example code that illustrates using a database with flask-login.</p>
  
  <p>What am missing here?</p>