Flask登录和Principal - 即使我已经登录,current_user也是匿名的

fan*_*nly 8 python flask flask-login flask-principal

我正在使用Flask Login和Principal进行身份和角色管理.我的需求直接来自文档.我的代码在这里:

@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
    # Set the identity user object
    identity.user = current_user

    # Add the UserNeed to the identity
    if hasattr(current_user, 'get_id'):
        print 'current_user ' + str(current_user.get_id())
        identity.provides.add(UserNeed(current_user.get_id))

    # Assuming the User model has a list of roles, update the
    # identity with the roles that the user provides
    if hasattr(current_user, 'roles'):
        if current_user.roles:
            for role in current_user.roles:
                identity.provides.add(RoleNeed(role.name))
Run Code Online (Sandbox Code Playgroud)

在我的登录代码中,我这样做:

identity_changed.send(current_app._get_current_object(),
                                  identity=Identity(user.user_id)
Run Code Online (Sandbox Code Playgroud)

登录时,信号按预期触发.在每个后续页面加载时,current_user是匿名的,并且没有用户ID,但所有@login_required函数的行为就像用户登录一样.Flask登录知道用户已登录,但由于某种原因,current_user不一致.

我错过了某处的基本配置点吗?

Mar*_*ase 6

我遇到了同样的问题!根本原因是Flask-Login和Flask-Principal在请求的"预处理"阶段按照Flask应用程序注册的顺序由Flask调用.如果您在注册Flask-Login之前注册Flask-Principal,那么@identity_loaded.connect_via(app)之前将调用它@login_manager.user_loader,因此current_user将返回匿名用户.

Flask-Principal文档示例显示Flask-Principal Flask-Login 之前注册的代码摘录.Tsk tsk!这是我最终在我的引导程序中做的事情:

login_manager = LoginManager()
login_manager.init_app(app)

# ...

principals = Principal(app) # This must be initialized after login_manager.
Run Code Online (Sandbox Code Playgroud)

然后在我的users.py视图文件中:

@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
    """ This function is called by Flask-Principal after a user logs in. """

    identity.user = current_user

    if isinstance(current_user, User):
        identity.provides.add(UserNeed(current_user.id))

    for permission in user.permissions:
        # Do permission-y stuff here.
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题.

编辑:我向项目提交了一份错误报告以供文档使用.