Python Flask и Graphene: неправильный запрос вызывает проблему безопасности
Я работаю над простой системой обмена сообщениями, где два разных пользователя могут отправлять сообщения друг другу. Прямо сейчас каждый пользователь опрашивает сервер, запрашивая самые новые сообщения, используя graphQL.
Проблема в том, что когда один пользователь, пользователь A, отправляет тонну сообщений (запросы на мутацию graphQL), в то время как другой пользователь, пользователь B, опрашивает, иногда кажется, что сообщения были отправлены пользователем B.
Я посмотрел глубже и обнаружил, что в тех случаях, когда сообщения были неправильно распределены, запрос на мутацию был вызван неверным запросом (как он был заполнен в контексте), и current_user
от flask_login
тоже неправильно. current_user
Кажется, зависит от запроса. Запрос был одним из запросов пользователя B (которые не являются мутациями).
Я проследил это немного назад и нашел точку, где контекст заполняется ( https://github.com/graphql-python/flask-graphql/blob/master/flask_graphql/graphqlview.py), но это было трудно выяснить, почему он получал неправильный запрос от Flask.
Мое лучшее предположение - что-то происходит с контекстным стеком запросов Flask, но это сложно отследить.
Я должен упомянуть, что аутентификация выполняется с использованием заголовка авторизации и что я попытался найти случай, когда пользователь был не аутентифицирован, но не смог.
Кажется, это происходит только тогда, когда я запускаю колбу напрямую, используя FLASK_ENV=production flask run
и, кажется, исчезает, когда я запускаю его с помощью gunicorn
, Тем не менее, это касается того, что аутентификация может быть настолько хрупкой.
Кто-нибудь видел эту проблему раньше? Есть ли в документации Flask что-то, объясняющее эту проблему, почему это происходит, и, что более важно, почему это не произойдет, когда я использую gunicorn
?
Соответствующие версии кода:
- Колба 1.0.2
- Flask-GraphQL 2.0.0
- Flask-Login 0.4.1
- Настой-SQLAlchemy 2.3.2
- графен 2.1.3
- графен-sqlalchemy 2.1.0
- graphql-core 2.1
- SQLAlchemy 1.2.12
Пример кода:
import graphene as gr
from graphql import GraphQLError
from flask_login import current_user
from ...models import Message
from .shared import MessageNode
class CreateMessage(gr.Mutation):
""" Send a message to a channel account """
message = gr.Field(MessageNode)
class Arguments:
body = gr.JSONString(required=True)
@login_required
def mutate(self, info, body):
# Make sure that the body is populated with something
if not (body.get("text") and not body.get("image")) and not (
not body.get("text") and body.get("image")
):
raise GraphQLError("Body must contain either text or an image")
new_message = Message(
body=body,
sender_account=current_user, # CURRENT USER IS INCORRECT HERE
)
db.session.add(new_message)
db.session.commit()
return CreateMessage(message=new_message)