Как пользователи могут получить доступ к моей базе данных Elasticsearch в моем Django SaaS? - PullRequest
0 голосов
/ 30 июня 2019

Допустим, у меня есть SaaS на основе бэкэнда Django, который обрабатывает данные пользователей и записывает все в Elasticsearch.Теперь я хотел бы предоставить пользователям доступ к поиску и запрашивать их данные, хранящиеся в ES, используя все возможные поисковые запросы, доступные в ES.Очевидно, что пользователь должен иметь доступ только к своим данным, а не к данным других пользователей.Я знаю, что это можно сделать разными способами, но мне интересно, что является безопасным и лучшим решением?На данный момент я храню все в одном индексе и набираю, как показано ниже, но я могу сделать это любым способом.

            "_index": "example_index",
            "_type": "example_type",
            "_id": "H2s-lGsdshEzmewdKtL",
            "_score": 1,
            "_source": {
                "user_id": 1,
                "field1": "example1",
                "field2": "example2",
                "field3": "example3"
            }

Я думаю, что лучшим способом было бы связать каждый документ с user_id.Пользователь отправит, например, запрос GET с телом и заголовок авторизации с токеном.Я бы использовал Token для извлечения идентификатора пользователя, например, таким образом

                    key = request.META.get('HTTP_AUTHORIZATION').split()[1]
                    user_id = Token.objects.get(key=key).user_id

. После этого я перенаправил бы его запрос в ES, и были бы возвращены только те данные, которые соответствуют требованиям и принадлежат этому пользователю.Конечно, я мог бы сделать это, как показано выше, где я также добавил поле user_id.Например, я мог бы использовать post_filter таким образом:

К каждому запросу я бы добавил что-то вроде этого:

,
    "post_filter": {
        "match": {
            "user_id": 1
        }
    }

Например, пользователь отправляет GET с телом

{
    "query": {
        "regexp": {
            "tag": ".*example.*"
        }
    }
}

, и я изменяю это в своем бэкэнде и перенаправлении на ES с телом:

{
    "query": {
        "regexp": {
            "tag": ".*example.*"
        }
    },
    "post_filter": {
        "match": {
            "user_id": 1
        }
    }
}

, но мне не кажется, что включение этого поля в _source являетсяотличная идея.Я почти уверен, что это может быть решено более оптимальным способом, чем post_filtering.Я вижу много информации об авторизации в ES, но не могу найти, как связать документ с user_id, а затем искать только его документы без post_filtering.Любые идеи?

ОБНОВЛЕНИЕ

Мое текущее решение выглядит так, как показано ниже, однако, как я уже говорил, я считаю, что это не оптимальный путь. Если у кого-то есть идея, как мне решить эту проблему описанным выше способом, я буду благодарен за помощь.

Я отправляю, например,

{
  "query": {
    "regexp": {
      "tag": ".*test.*"
    }
  }
}

В бэкэнде DjangoЯ просто делаю

        key = request.META.get('HTTP_AUTHORIZATION').split()[1]

        user_id = Token.objects.get(key=key).user_id

        body = json.loads(request.body)

        body['post_filter'] = {"match": {"user_id": user_id}}

        res = es.search(index="pictures", doc_type="picture", body=body)

        output = []

        for hit in res['hits']['hits']:
            output.append(hit["_source"])

        return Response(
            {'output': output},
            status=status.HTTP_200_OK)

1 Ответ

0 голосов
/ 30 июня 2019

Вasticsearch 7.1 теперь у вас есть базовая защита в бесплатной версииasticsearch. Благодаря этому вы можете по отдельности контролировать доступ вашего пользователя.

...