我正尝试使用Flask构建Web应用程序。我的首页(/)会检查是否有人登录,如果不是,请显示要求输入用户名和密码的表单。 Whne用户从提交,这些凭证被验证,并且如果有效用户对象被创建和发送使用其login_user
功能flask_login:Flask-Login将我登录,但每当我做GET请求时,立即再次登出我
@app.route('/', methods=['POST', 'GET'])
def front():
tem = jinjaEnv.get_template("front_page.html")
msg = "(no message)"
if request.method=='POST':
un = request.form['username']
pw = request.form['password']
user = modsal.getUser(un, pw)
if user.is_authenticated:
login_user(user)
msg = ("<span style='color:#080; background:#efe;'>"
"<i class='fa fa-check-circle'></i> "
"You are logged in</span>")
else:
msg = ("<span style='color:#800; background:#fee;'>"
"<i class='fa fa-times-circle'></i> "
"login failed</span>")
#//if
h = tem.render(
msg = msg,
)
return h
这工作得很好,并且用户已登录
但是,当我对另一个页面(甚至是同一个页面)执行GET请求时,flask-login会将我注销。我有一个user_loader
回调,但它没有被flask_login称为:
@loginManager.user_loader
def load_user(userId):
""" returns a user object (for Flask_login).
Given a userId (which is the username), returns an Engineer object
(if it was a valid user), or None if not.
@return Engineer|None
"""
pr("%s-=-=- userId=%r -=-=-%s",
termcolours.TermColours.MAGENTA,
userId,
termcolours.TermColours.NORMAL)
from modsal import session, Engineer
u = session.query(Engineer).filter(
Engineer.username == username).one_or_none()
# Note that if a user wasn't found, (u) will be None
# here, which is what loginManager wants.
return u
(注:pr()
打印调试代码到标准错误。)
我写了一些调试代码,看看发生了什么事情。每个请求之前,该打印会话cookie:
@app.before_request
def checkSessionCookie():
sessionStr = request.cookies.get('session_8210')
decoded = decookie.decodeCookie(sessionStr)
pr("%s***** decoded=%s%s",
termcolours.TermColours.MAGENTA,
decoded,
termcolours.TermColours.NORMAL)
在我Jinja2的模板,我在显示已登录用户的用户名每个页面顶部的一面旗帜。这是通过调用currentUserName()
,它返回一个包含用户名的字符串,或""
如果没有实现:
def currentUserName():
pr("%s current_user=%s %s",
termcolours.TermColours.RED,
current_user,
termcolours.TermColours.NORMAL)
if (not current_user) or current_user.is_anonymous:
prvars("current_user")
return ""
try:
un = str(current_user.username)
prvars("un")
return un
except:
return ""
jinjaEnv.globals['currentUserName'] = currentUserName
注意,这个函数在执行时还会打印出调试代码。
当我与麦克的用户名登录,然后做一个GET /请求,我的标准错误是这样的:
checkSessionCookie():113: ***** decoded={"_fresh":true,"_id":{" b":"MDY5N2MyNDhmZGU4YWVmZmE5NzMzNjEwODQwYmE2NWNhMmU2YzI4MDRiMWZlMmRiNmFhYjg2MmE5NDMyMGY2Y2RiYjBjMTNjOWYzMjE3ODk0YWVmMDk1YjA2ZWJlZjkyNmQ3MDE1MDdkZjI2MDRhNzg2MTI1NzFkOTU0MmJkM2M="},"csrf_token":{" b":"MTVlNGY4MDBjNWQwNThmODhjNzc2ZGZlMzRjODllNmQ5YzU5MWZlMA=="},"user_id":"Mike"}
currentUserName():72: current_user=<flask_login.AnonymousUserMixin object at 0x7f2f10bff690>
currentUserName():74
127.0.0.1 - - [10/Feb/2016 11:54:51] "GET/HTTP/1.1" 200 -
需要注意的是:
请求之前,会话cookie有正确的用户名称Mike
my
load_user()
函数不会被flask_login调用当Jinja2的呈现为/模板,瓶的
current_user
现在是匿名用户
那么,为什么烧瓶登录改变我current_user
从正确的登录用户,一位不愿透露姓名吗?我该如何解决这个问题?我使用Flask(0.10.1),Flask-Login(0.3.2),其危险性(0.24)。
编辑:
我的用户类被称为Engineer
。这是一个SQLAlchemy类,它也从Flask-login的UserMixin
继承。
class Engineer(Base, UserMixin):
__tablename__ = 'tblEngineers'
engineerId = Column('EngineerID', Integer(), primary_key=True)
username = Column('Username', String())
password = Column('Password', String())
firstName = Column('FirstName', String())
lastName = Column('LastName', String())
engineer = Column('Engineer', Integer())
def __repr__(self):
s = "<Engineer %d %r %r>" % (
self.engineerId, self.username, self.engineer)
return s
#========== stuff Flask-login needs: ==========
def get_id(self):
result = unicode(self.username)
pr("get_id() => %r", result)
return result
不幸的是,当flask_login自动将我注销时,get_id()
函数没有被调用。
的用户名和密码的代码的例子都验证了'用户= modsal.getUser(联合国,PW)'。此外,目前我更关心的是**而不是安全。 –
@PhilHunt,我已经更新了我的答案。我能够重现您的问题这是您的用户模型上的get_id。请检查上面的解决方案。 – m1yag1
我'get_id()'函数看起来像这样 高清get_id(个体经营): 结果=的Unicode(self.username) PR( “get_id()=>%R”,结果) 返回结果 不幸的是,不会被调用。 –