具有多个用户类别和SSO的烧瓶登录

时间:2020-06-05 23:48:56

标签: python flask flask-sqlalchemy flask-login

这里是烧瓶初学者。我的烧瓶登录有三个用户类。 GoogleUser和FacebookUser使用SSO,并且不需要密码字段:

from InstaFlix import db, login_manager
from datetime import datetime
from flask_login import UserMixin

# Get a user by their ID
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
    email = db.Column(db.String(100), unique =True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    name = db.Column(db.String(100), nullable=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    profile_pic = db.Column(db.String(100), unique=False, nullable=False, default='default.jpg')

class GoogleUser(db.Model, UserMixin):
    id = db.Column(db.String(20), primary_key=True) 
    email = db.Column(db.String(100), unique =True, nullable=False)
    name = db.Column(db.String(40), unique=True, nullable=False)
    profile_pic = db.Column(db.String(100), unique=False, nullable=True)

class FacebookUser(db.Model, UserMixin):
    id = db.Column(db.String(20), primary_key=True) 
    email = db.Column(db.String(100), unique =True, nullable=False)
    name = db.Column(db.String(40), unique=True, nullable=False)
    profile_pic = db.Column(db.String(100), unique=False, nullable=True)

我也想根据用户选择的路线来加载特定的类。例如,https://127.0.0.1:5000/fb将允许用户登录。然后调用类FacebookUser将其信息保存到其中。

但是,我一次只能返回一堂课。

如何根据路由如何使用load_user()函数调用特定的用户类?

截至目前,根据我要查询的类,只能加载一个类。

1 个答案:

答案 0 :(得分:2)

IMO,无需为具有不同类型/角色的用户创建多个模型,您可以创建一个新列来存储用户类型。此外,GoogleUserFacebookUser模型中的列与User模型完全相同。我建议只对它们使用一个User类。更加优雅和方便。

如果要区分不同的用户类型,只需添加一个新列,如下所示:

class User(db.Model, UserMixin):
    # ...
    login_type = db.Column(db.String(20))

如果确实需要使用多个用户模型,则可以使用session存储登录类型,例如:

from flask import session

@oauth_bp.route('/callback/<provider_name>')
def oauth_callback(provider_name):
    if provider_name not in providers.keys():
        abort(404)

    provider = providers[provider_name]
    response = provider.authorized_response()
    session['login_type'] = provider_name

然后在load_user中读取它,根据其值使用不同的用户模型:

from flask import session

@login_manager.user_loader
def load_user(user_id):
    login_type = session.get('login_type')
    if login_type == 'google':
        return GoogleUser.get(user_id)
    elif login_type == 'facebook':
        return FacebookUser.get(user_id)
    else:
        return User.query.get(user_id)