Flask-Login вводит меня в систему, но всякий раз, когда я делаю запрос GET, сразу же снова выводит меня из системы

Я пытаюсь создать веб-приложение с помощью Flask. Моя главная страница (/) проверяет, вошел ли кто-нибудь в систему, а если нет, отображает форму с запросом имени пользователя и пароля. Когда пользователь отправляет from, эти учетные данные проверяются, и, если они действительны, пользовательский объект создается и отправляется в flask_login с использованием его функции login_user:

@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 отображает шаблон для /, current_user Flask теперь является анонимным пользователем.

Итак, почему flask-login меняет мой current_user с правильного зарегистрированного пользователя на анонимного? И как мне это исправить?

FWIW, я использую Flask (0.10.1), Flask-Login (0.3.2), это опасно (0.24).

Изменить:

Мой пользовательский класс называется Engineer. Это класс SQLAlchemy, который также наследуется от класса UserMixin во Flask-login.

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

К сожалению, функция get_id() не вызывается, когда flask_login автоматически выводит меня из системы.


person Phil Hunt    schedule 10.02.2016    source источник


Ответы (1)


Вам необходимо проверить свою модель пользователя. Вам нужно убедиться, что модель возвращает правильный идентификатор, который вы хотите использовать. По умолчанию он загружается через свойство id модели, однако я вижу, что вы используете имя пользователя. Вероятно, вам нужно добавить:

def get_id(self):
    return self.username

Вы можете увидеть пример, основанный на отправленном вами коде, здесь.

person m1yag1    schedule 10.02.2016