Flask-login未按预期工作

时间:2014-08-07 09:46:48

标签: python session oauth flask flask-login

Flask-login似乎没有"将用户保存在会话中#34;。在/login处理程序上,用户已通过login_user(user, remember=True)登录并记住,但在打开任何其他页面时,返回的用户是AnonymousUser,而不是{{1}的登录用户}。class。

这是一个简单的用户类,附带了从另一个用于数据库存储的类中获取用户的方法。

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)

我不需要密码进行身份验证,我使用OAuth,因此我想检查存储在用户表中的用户令牌。我怀疑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 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)

在第二种情况下:

<User u'stackoverflow'>

所以,基本上很明显,虽然<flask_login.AnonymousUser object at 0x02D455F0> 设法登录用户并设置了login_user(),但在加载其他视图时current_userAnonymousUser返回。

有趣的是,重要的是我从未看到current_user字符串,因此我无法确认是否正在调用gettingtoken函数。

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

2 个答案:

答案 0 :(得分:1)

我尝试了你的代码,它确实对我有用(有了更改) - 你必须在你所展示的内容之外做错了。特别是,readingtoken按预期输出,current_useruser视图中的登录用户。

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

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)

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

  • Flask 0.10.1
  • Flask-Login 0.2.11
  • itsdangerous 0.24

此外,您可能希望将TwitterUserUserMixin一起使用,而不是包装1&#34;用户&#34;对象在另一个内部。

答案 1 :(得分:0)

问题可能在于您使用自定义会话界面覆盖Flask的app.session_interface。 Flask使用flask.sessions.SecureCookieSessionInterface,而Flask-Login似乎依赖于其中的某些属性。

您是否可以将MongoDB用作数据库和/或使用MongoEngine作为ODM? (它可能会与其他app.session_interface覆盖一起发生) 我有一个完全相同的问题,没有调用token_load,调试它大约一天,只是发现问题是我在应用程序中使用的MongoEngineSessionInterface。

不完全确定它是否适用于此处,但在我的情况下,问题是Flask-Login会对其代码中的&#39; user_id&#39;进行检查。在会话中,当使用MongoEngineSessionInterface时,它始终是,因此它永远不必调用我的令牌加载处理程序。

简单地删除该会话界面作为一种解决方法对我有用。

相关问题