Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flask-login: can't understand how it works

I'm trying to understand how Flask-Login works.

I see in their documentation that they use a pre-populated list of users. I want to play with a database-stored users list.

However, I don't understand some things in this Flask-Login module.

@login_manager.user_loader def load_user(userid):     #print 'this is executed',userid     return user(userid, 'asdf') 

This code will be called at every request? This is used to load all the details of my user object?

For now, I have this code:

@app.route('/make-login') def make_login():     username = 'asdf'     password = 'asdf'     user_data = authenticate(username, password)     user_obj = user(user_data[0], user_data[1])     login_user(user_obj)     return render_template('make-login.html') 

When I access /make-login, I want to log in.

My user class:

class user(object):     def __init__(self, id, username, active=True):         self.username = username         self.id = id         #self.active = active     def is_authenticated(self):         return True        def is_active(self):         return True      def is_anonymous(self):         return False      def get_id(self):         return 5 

Also, I wrote another two functions for authenticate/register

def authenticate(username, password):      cursor = db.cursor()     password = md5.md5(password).hexdigest()     try:         query = "SELECT * FROM `users` WHERE `username` = %s AND `password` = %s"         cursor.execute(query, (username, password))         results = cursor.fetchall()         #print results[0][0]         #print "here i am"         if not results:             return False         else:             user_data = [results[0][0], results[0][1]]             return user_data             #self.authenticated = True             #self.user_id = results[0][0]             #session['username']  = results['username']             #print type(results)     except db.Error, e:         return 'There was a mysql error'      def register(username, password, email, *args):     cursor = db.cursor()     password = md5.md5(password).hexdigest()     try:         #query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('%s', '%s', '%s')" % (username, password, email)         query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES (%s, %s, %s)"         cursor.execute(query, (username, password, email))         db.commit()         return True     except db.Error, e:         print 'An error has been passed. %s' %e         db.rollback()         return False 

I don't know how to make this Flask-Login work with MySQL. Also, I don't know if the user are logged-in. How can I get the user ID or the username?

Anyone can explain me in some rows how this Flask-Login works?

like image 520
Sorin Vladu Avatar asked Aug 22 '12 14:08

Sorin Vladu


People also ask

What does Flask-Login do?

Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users' sessions over extended periods of time. It will: Store the active user's ID in the Flask Session, and let you easily log them in and out.

Is Flask-login safe?

the login process seems secure. But you didn't check the potential existing user in the signup form, or existing email address. Unless this is managed by the underlying User schema. And you should require a minimal password complexity.


2 Answers

Flask-login will try and load a user BEFORE every request. So yes, your example code below will be called before every request. It is used to check what userid is in the current session and will load the user object for that id.

@login_manager.user_loader def load_user(userid):     #print 'this is executed',userid     return user(userid, 'asdf')         

If you look at the Flask-login source code on github, there is a line under function init_app which goes:

app.before_request(self._load_user) 

So before every request, the _load_user function is called. The _load_user functions actually calls another function "reload_user()" based on conditions. And finally, reload_user() function calls your callback function that you wrote (load_user() in your example).

Also, flask-login only provides the mechanism to login/logout a user. It does not care if you are using mysql database.

like image 38
codegeek Avatar answered Oct 03 '22 05:10

codegeek


Flask-login doesn't actually have a user backend, it just handles the session machinery to help you login and logout users. You have to tell it (by decorating methods), what represents a user and it is also up to you to figure out how to know if a user is "active" or not (since being "active" can mean different things in different applications).

You should read the documentation and be sure what it does and does not do. Here I am only going to concentrate on wiring it up with the db backend.

To start off with, define a user object; which represents properties for your users. This object can then query databases, or LDAP, or whatever and it is the hook that connects the login mechanism with your database backend.

I will be using the login example script for this purpose.

class User(UserMixin):     def __init__(self, name, id, active=True):         self.name = name         self.id = id         self.active = active      def is_active(self):         # Here you should write whatever the code is         # that checks the database if your user is active         return self.active      def is_anonymous(self):         return False      def is_authenticated(self):         return True 

Once you have the user object created, you need to write a method that loads the user (basically, creates an instance of the User class from above). This method is called with the user id.

@login_manager.user_loader def load_user(id):      # 1. Fetch against the database a user by `id`       # 2. Create a new object of `User` class and return it.      u = DBUsers.query.get(id)     return User(u.name,u.id,u.active) 

Once you have these steps, your login method does this:

  1. Checks to see if the username and password match (against your database) - you need to write this code yourself.

  2. If authentication was successful you should pass an instance of the user to login_user()

like image 170
Burhan Khalid Avatar answered Oct 03 '22 03:10

Burhan Khalid