Flask-Login登录我,但每当我做GET请求时,立即再次登出我

时间:2016-02-10 12:25:27

标签: python flask flask-login

我正在尝试使用Flask构建一个Web应用程序。我的首页(/)检查是否有人登录,如果没有,则显示一个要求输入用户名和密码的表单。当用户提交from时,将验证这些凭据,如果有效,则创建用户对象并使用其login_user函数将其发送到flask_login:

@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()将调试代码输出到stderr。)

我写了一些调试代码,看看是怎么回事。在每个请求之前,这将打印会话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

请注意,此函数还会在执行时打印出调试代码。

当我使用Mike的用户名登录然后执行GET /请求时,我的stderr看起来像这样:

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 -

请注意:

    在请求之前
  1. ,会话cookie具有正确的用户名Mike

  2. 我的load_user()函数没有被flask_login调用

  3. 当Jinja2为/呈现模板时,Flask&#39; current_user现在是匿名用户

  4. 那么,为什么flask-login会将我的current_user从正确的登录用户更改为匿名用户?我该如何解决这个问题?

    FWIW,我使用Flask(0.10.1),Flask-Login(0.3.2),itdangerous(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()函数不会被调用。

1 个答案:

答案 0 :(得分:0)

您需要检查您的用户模型。您需要确保模型返回您要使用的正确ID。默认情况下,它将通过模型的id属性加载,但我看到你使用的是用户名。您可能需要添加:

def get_id(self):
    return self.username

您可以根据提交的代码here.

查看示例