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_user
以AnonymousUser
返回。
有趣的是,重要的是我从未看到current_user
字符串,因此我无法确认是否正在调用gettingtoken
函数。
我已经提出了另一个问题,但经过进一步审查,我认为这个问题与那里描述的问题无关,因此这个问题背后的原因。
答案 0 :(得分:1)
我尝试了你的代码,它确实对我有用(有了更改) - 你必须在你所展示的内容之外做错了。特别是,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)
并看到插件版本是正确的;我的是
此外,您可能希望将TwitterUser
与UserMixin
一起使用,而不是包装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时,它始终是,因此它永远不必调用我的令牌加载处理程序。
简单地删除该会话界面作为一种解决方法对我有用。