Flask-login未按预期工作

won*_*ile 7 python session oauth flask flask-login

Flask-login似乎不是"在会话中保存用户".在/login处理程序上,用户登录并记住通过login_user(user, remember=True),但在打开任何其他页面时,返回的用户是AnonymousUser,而不是来自User类的登录用户.

下面是简单的用户类,其中包含从另一个用于数据库存储的类中获取用户的方法.

class User():
    def __init__(self, user):
        self.user = user

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    # Flask-Login is technically able to support these.
    # We don't swing that way.
    def is_anonymous(self):
        return False

    @staticmethod
    def get(userid):
        print 'getuser instance'
        return User(find_user_by_username(userid))

    def get_id(self):
        return self.user.username

    def __repr__(self):
        return '<User %r>' % self.user.username

    def get_auth_token(self):
        print 'gettingtoken'
        data = [self.user.id, self.user.username]
        return login_serializer.dumps(data)
Run Code Online (Sandbox Code Playgroud)

获取用户和用户加载器的方法如下:

def find_user_by_username(username):
    print 'find by find_user_by_username'
    i = TwitterUser.query.filter_by(username=username).first()
    if i is not None:
        print 'found user'
        return i
    print 'didnt found'
    return None

@login_manager.user_loader
def load_user(userid):
    print "userloader"
    return User.get(userid)

@login_manager.token_loader
def token_load(token):
    print 'readingtoken'
    max_age = app.config["REMEMBER_COOKIE_DURATION"].total_seconds()
    data = login_serializer.loads(token, max_age=max_age)
    print 'data: ', data
    user = User.get(data[1])
    if user:
        return user
    return None
Run Code Online (Sandbox Code Playgroud)

我不需要密码进行身份验证,我使用OAuth,因此我想检查存储在用户表中的用户令牌.我怀疑这个token_load()或者get_auth_token()方法有问题.

两个示例路由我做了解释行为是:

@app.route('/login')
def login():
    user = User.get('stackoverflow')
    print "login"
    if user.user is None:
        newUser = TwitterUser('stackoverflow', 'email@gmail.com', 0, 0, 0, 0, 'something', 'something')
        db.session.add(newUser)
        db.session.commit()
        print 'added user'
        return redirect('/login')
    login_user(user, remember=True)
    return str(current_user)

@app.route('/user')
def user():
    return str(current_user)
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,这些调试返回值返回:

<User u'stackoverflow'>
Run Code Online (Sandbox Code Playgroud)

在第二种情况下:

<flask_login.AnonymousUser object at 0x02D455F0>
Run Code Online (Sandbox Code Playgroud)

因此,基本上,很明显,虽然 login_user()设法登录用户并设置current_user应该是,但是当加载一些其他视图时,AnonymousUser返回为current_user.

一个有趣的事情,可能很重要的是我从来没有看到过gettingtoken字符串,所以我无法确认token_load函数是否被调用.

我已经提出了另一个问题,但经过进一步审查,我认为这个问题与那里描述的问题无关,因此这个问题背后的原因.

Ant*_*ala 0

我尝试了你的代码,它确实对我有用(经过更改)-你一定在此处显示的内容之外做了一些错误的事情。特别是,readingtoken按预期输出,并且current_user是登录用户的视图user

特别是,检查您是否已将登录管理器安装到应用程序中:

app = Flask(__name__)
app.config['SECRET_KEY'] = '123123123'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.session_protection = "strong"
login_serializer = URLSafeTimedSerializer(app.secret_key)
Run Code Online (Sandbox Code Playgroud)

并查看插件版本是否正确;我的是

  • 烧瓶0.10.1
  • Flask-登录 0.2.11
  • 很危险 0.24

另外,您可能希望使用TwitterUserwithUserMixin而不是将 1 个“用户”对象包装在另一个对象中。