title: How the users can access my Elasticsearch database in my Django SaaS?
body: <p>Let's say that I have a SaaS based on Django backend that processes the data of the users and write everything to the Elasticsearch. Now I would like to give users access to search and request their data stored in ES using all possible search requests available in ES. Obviously the user should have only access to his data, not to other user's data. I am aware that it can be done in a lot of different ways but I wonder what is safe and the best solution? At this point I store everything in one index and type in the way shown below but I can do this in any way. </p>
  
  <pre><code>            "_index": "example_index",
              "_type": "example_type",
              "_id": "H2s-lGsdshEzmewdKtL",
              "_score": 1,
              "_source": {
                  "user_id": 1,
                  "field1": "example1",
                  "field2": "example2",
                  "field3": "example3"
              }
  </code></pre>
  
  <p>I think that the best way would be to associate every document with the user_id. The user would send for example GET request with body and authorization header with Token. I would use Token to extract id of the user for example in this way</p>
  
  <pre><code>                    key = request.META.get('HTTP_AUTHORIZATION').split()[1]
                      user_id = Token.objects.get(key=key).user_id
  </code></pre>
  
  <p>After this I would redirect his request to ES and only data that meet requirements and belongs to this user would be returned. Of course I could do this like shown above where I also add field <code>user_id</code>. For example I could use <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-post-filter.html" rel="nofollow noreferrer">post_filter</a> in this way:</p>
  
  <p>To every request I would add something like this:</p>
  
  <pre><code>,
      "post_filter": {
          "match": {
              "user_id": 1
          }
      }
  </code></pre>
  
  <p>For example the user sends GET with body</p>
  
  <pre><code>{
      "query": {
          "regexp": {
              "tag": ".*example.*"
          }
      }
  }
  </code></pre>
  
  <p>and I change this in my backend and redirect request to ES with body:</p>
  
  <pre><code>{
      "query": {
          "regexp": {
              "tag": ".*example.*"
          }
      },
      "post_filter": {
          "match": {
              "user_id": 1
          }
      }
  }
  </code></pre>
  
  <p>but it doesn't seem to me that including this field in <code>_source</code> is a good idea. I am almost sure that it can be solved in a more optimal way than <code>post_filtering</code>. I see a lot of information about authorization in ES however I can’t find how can I associate document with <code>user_id</code> and then search only his documents without <code>post_filtering</code>. Any ideas?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>My current solution looks in they way shown below however as I mentioned I believe that it is not optimal way. <strong>If anyone has an idea how can I solve this in the way described above I will be grateful for help.</strong></p>
  
  <p>I send for example </p>
  
  <pre><code>{
    "query": {
      "regexp": {
        "tag": ".*test.*"
      }
    }
  }
  </code></pre>
  
  <p>In Django backend I just do</p>
  
  <pre><code>        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)
  </code></pre>