Python 烧瓶登录未按预期工作
Python 烧瓶登录未按预期工作,python,session,oauth,flask,flask-login,Python,Session,Oauth,Flask,Flask Login,Flask login显示为不“在会话中保存用户”。在/login处理程序上,用户通过login\u user(user,memory=True)登录和记忆,但打开任何其他页面时,返回的用户是匿名用户,而不是用户类中的登录用户 下面是一个简单的用户类,它附带了从另一个用于数据库存储的类获取用户的方法 class User(): def __init__(self, user): self.user = user def is_authenticated(self
Flask login
显示为不“在会话中保存用户”。在/login
处理程序上,用户通过login\u user(user,memory=True)
登录和记忆,但打开任何其他页面时,返回的用户是匿名用户
,而不是用户
类中的登录用户
下面是一个简单的用户类,它附带了从另一个用于数据库存储的类获取用户的方法
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,所以我想检查存储在用户表中的用户令牌。我怀疑token\u load()
或get\u auth\u 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\u user()
设法登录用户并将current\u user
设置为它应该的状态,但是当加载其他视图时,AnonymousUser
作为current\u user
返回
有一件有趣的事情,可能很重要的是,我从未看到gettingtoken
字符串,因此我无法确认是否调用了token\u load
函数
关于这一点,我已经提出了另一个问题,但在进一步研究后,我认为这个问题与这里描述的问题无关,因此这一问题背后的推理是这样的。我尝试了你的代码,它确实对我有效(经过更改)-你一定做了一些超出此处显示范围的错误。特别是,
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)
并确保插件版本正确;我的是
- 烧瓶0.10.1
- 第0.2.11节
- 这是危险的0.24
此外,您可能希望将
TwitterUser
与UserMixin
一起使用,而不是将一个“user”对象包装在另一个对象中。问题可能是您正在使用自定义会话接口覆盖Flask的app.session\u接口。
Flask使用Flask.sessions.SecureCookieSessionInterface,Flask登录似乎取决于其中的某些属性
您可能会使用MongoDB作为数据库和/或MongoEngine作为ODM吗?(其他app.session_接口覆盖也可能发生这种情况)
我也遇到了同样的问题,token_load没有被调用,调试了大约一天,结果发现问题出在我在应用程序中使用的MongoEngineSessionInterface上
不确定它是否适用于这里,但在我的例子中,问题是Flask Login在其代码中检查“user_id”是否在会话中,并且在使用MongoEngineSessionInterface时始终如此,因此它不必调用我的令牌加载处理程序
简单地删除该会话界面作为一种解决方法对我来说很有效。如果有人嘲笑我,请检查
login\u serializer.loads()
是否在第二个视图中返回正确的用户。我敢打赌它不会。我有一些调试打印语句,它们没有出现在控制台中,所以我怀疑这部分代码是否正在运行。关于令牌写入,我甚至尝试了md5()
围绕data=[self.user.id,md5(self.user.username)]
然后return login\u serializer.dumps(data)
,因此用户数据基本上是散列的,但仍然是一样的。感谢大家的提醒,我确实有这个方法,但忘了在注释中包含它。我在上面的代码块描述中提到了它,其中包括get
自定义方法和令牌加载器,但忘记了复制它。所以,不是这样,我有用户加载器。谢谢你的洞察力。我没有使用MongoDB,我使用SQLAlchemy和MySQL进行数据库存储。我检查了一些可能的位置,我确实从flask
导入会话
,从flask\u登录
我使用登录管理器,需要登录,登录用户,当前用户,注销用户
。除此之外,它还从危险的进口URLSafeTimedSerializer中引入了另一个进口TM,这可能是造成这种情况的一些原因。我通过手动使用session解决了这个问题,但这限制了我的选择,并消除了应用程序中的一些选项。我一定会在接下来的几天里检查这个,看看这个会有什么帮助!
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)