Создание сеанса в Google appengine (Python) - простое завершение аутентификации

У нас есть приложение, работающее в Google Appengine (Python 2.7), которое использует Simple Auth для входа в систему и каркас webapps2. В настоящее время мы поддерживаем только вход в Facebook.

Проблема: время от времени вход в Facebook - создание сессии не работает должным образом. Это происходит не всегда, и это влияет только на 10 % от общего трафика на сайте. Обратный звонок от авторизации Facebook на наш сайт происходит правильно, мы также можем получить токен авторизации Facebook. Но создание сеанса само по себе не удается.

Поток управления: 1) Пользователь нажимает кнопку "Войти через Facebook" на нашей странице. 2) Пользователь перенаправляется на Facebook для получения разрешений (при первом входе в систему). 3) Пользователь перенаправляется обратно на наш сайт после предоставления соответствующей авторизации в Facebook. 4) Авторизационный токен пользователя получен на нашем сайте, и мы извлекаем информацию о пользователе из API графа Facebook, используя этот токен. 5) Создается сеанс и заголовок cookie устанавливается на объекте ответа (место, где в данный момент возникает проблема). 6) Пользователь перенаправлен на наша панель инструментов (панель инструментов - это экран, который отображается только для вошедших в систему пользователей. Поэтому, если сессия / файл cookie не созданы должным образом, пользователь будет перенаправлен обратно на страницу входа).

Средство уже опробовано: мое первое предположение состояло в том, что создание сеанса занимает больше времени, чем выполнение следующей строки кода. Это может произойти в случае, если создание сеанса является асинхронным процессом. Поэтому я включил небольшую задержку между строкой создания сеанса и следующей строкой. Идея заключалась в том, чтобы дать достаточно времени для того, чтобы зафиксировать внесенные изменения. Кроме того, если сеанс не был действительно создан в конце времени ожидания, я пытаюсь воссоздать объект сеанса.

ok, user = self.auth.store.user_model.create_user(auth_id, **_attrs)
logging.info("creating user : "+str(ok)+" | user" +str(user))
if ok:
    self.auth.set_session(self.auth.store.user_to_dict(user))
    logging.info("User: "+str(self.auth.get_user_by_session()))
    if( self.auth.get_user_by_session() is None ):
        logging.info("Existing user logging in.. But the set session didn't work So wait for sometime")
        time.sleep(0.5)
        if( self.auth.get_user_by_session() is None ):
            logging.info("Existing user logging in.. But the set session didn't work So try again")
            self.auth.set_session(self.auth.store.user_to_dict(user))

Но вышеупомянутая техника не работает. Итак, в моем диагнозе есть недостаток.

Запрос помощи в решении этой проблемы. Пожалуйста, дайте мне знать, если вам нужно больше информации о том же.

1 ответ

В общем, ожидание плохое оправдание для синхронизации.

В любом случае вы захотите покопаться в своей библиотеке аутентификации для расследования. Вы не хотите, чтобы auth.set_session был асинхронным. Сделайте это синхронно. Это должно облегчить жизнь.

Узнайте, как работает get_user_by_session(). Проблема, которую вы описываете, очень похожа на возможную последовательность действий. Это может произойти, если get_user_by_session() выдает операцию запроса к хранилищу данных, которая может в конечном итоге вернуть согласованные результаты. Для вашей операции get_user_by_session() вам нужны строго согласованные результаты, поэтому библиотека должна использовать операцию get хранилища данных. Фактически, поскольку вы только что создали пользователя и сеанс, библиотека должна была кэшировать эту информацию и не должна вообще попадать в хранилище данных.

Библиотека, являющаяся python, должна быть в состоянии пройтись по коду библиотеки и выяснить, что происходит.

Другие вопросы по тегам