简体   繁体   中英

multiple user for flask_login

I have two user models for flask_login.:

class Admin(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30))
    password_hash = db.Column(db.String(200))

class Merchant(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30))
    password_hash = db.Column(db.String(200))

Now I want to load user in session:

@login_manager.user_loader
def load_user(user_id):
    pass

I want to know how to load user from two models.

Here's a solution i've been using so far, i don't know its flaws, but it's the answer you're looking for.

Assuming you have multiple account types, the key is to use the session to store that account type upon login, and use it like this:

@login_manager.user_loader
def load_user(user_id):
  if session['account_type'] == 'Admin':
      return Admin.query.get(int(user_id))
  elif session['account_type'] == 'Merchant':
      return Merchant.query.get(int(user_id))
  else:
      return None

Providing routes and html is not necessary, you could implement them as you wish, either by :

  • Creating different routes for different user types.
  • Adding a select field in the login form with one route for all user types.

This thread provides further information about sessions and how to secure them, you should check it out.

I understand that your choice to keep your classes separated, but consider merging the commun attributes together in one parent class leaving only the id to prevent foreign keys problems, like this:

class Person(db.Model):
  __abstract__ = True
  name = db.Column(db.String(30))
  password_hash = db.Column(db.String(200))

class Admin(Person, UserMixin):
  id = db.Column(db.Integer, primary_key=True)

class Merchant(Person, UserMixin):
  id = db.Column(db.Integer, primary_key=True)

As the parent table is abstract it won't be created, but its children will.

#You can create a permission 
admin_permission = Permission(RoleNeed('admin'))

#protect a view with a principal for that need
@app.route('/admin')
@admin_permission.required()
def do_admin_index():
     return Response('Only if you are an admin)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM