在 Shopware 6 中使用用户名+密码连接 Elasticsearch

Connecting Elasticsearch with Username + password in Shopware 6

我想将我的 Shopware 6.4 安装连接到 Elasticsearch 实例。我的 Elasticsearch 实例受用户名和密码保护。

我无法在 Shopware 6 和 Elasticsearch 之间建立连接,因为我找不到将用户名和密码传递给配置的方法。

.env

SHOPWARE_ES_HOSTS="http://username:password@elasticsearch.local:9201"
SHOPWARE_ES_ENABLED="1"
SHOPWARE_ES_INDEXING_ENABLED="1"
SHOPWARE_ES_INDEX_PREFIX="sw"

当 运行 bin/console es:status 我得到一个 401 状态码。

Unknown 401 error from Elasticsearch null

当我尝试通过 curl 连接到我的 Elasticsearch 实例时,我可以毫无问题地连接:

curl -u 'user:password' http://elasticsearch.local:9201
{

  "name" : "elasticsearch",
  "cluster_name" : "es-cluster-01",
  "cluster_uuid" : "dRsu0d_PQKyTI5RDe_r79Q",
  "version" : {
    "number" : "7.14.1",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "66b55ebfa59c92c15db3f69a335d500018b3331e",
    "build_date" : "2021-08-26T09:01:05.390870785Z",
    "build_snapshot" : false,
    "lucene_version" : "8.9.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

如何在 Shopware 中传递用户名和密码以连接到我的 Elasticsearch 实例?

配置通过

传递
   config/services/defaults.xml:12

致客户:

   <service id="Elasticsearch\Client" public="true">
        <factory class="Shopware\Elasticsearch\Framework\ClientFactory" method="createClient" />
        <argument>%elasticsearch.hosts%</argument>
        <argument type="service" id="shopware.elasticsearch.logger" />
        <argument>%kernel.debug%</argument>
    </service>

传递给 clientbuilder 的主机:

 \Shopware\Elasticsearch\Framework\ClientFactory::createClient

根据

它可能有一个用户并通过那里。

有:

vendor/elasticsearch/elasticsearch/src/Elasticsearch/ClientBuilder.php:676

$host = $this->extractURIParts($host);

并且:

/**
 * @throws InvalidArgumentException
 */
private function extractURIParts(string $host): array
{
    $parts = parse_url($host);

    if ($parts === false) {
        throw new InvalidArgumentException(sprintf('Could not parse URI: "%s"', $host));
    }

    if (isset($parts['port']) !== true) {
        $parts['port'] = 9200;
    }

    return $parts;
}

这只是一个 parse_url 调用,应该提取用户并通过。

长话短说:您的方法实际上应该有效。

为了进一步调试,我建议 xdebug 进入

 \Elasticsearch\ClientBuilder::extractURIParts

或放置一些临时调试代码:

private function extractURIParts(string $host): array
{
    $parts = parse_url($host);

    var_dump($parts); die();

您的用户名或密码是否包含一些可能导致问题的特殊字符?

更新 - 找到解决方案 问题是密码中的特殊字符。 .env 文件中需要对 $ 等特殊字符进行转义。

如果密码是 1233 那么正确的字符串应该是:

SHOPWARE_ES_HOSTS="http://username:123$123@elasticsearch.local:9201"

所以 $ 需要用反斜杠转义 (\)。

编辑:密码也可能是 URL 编码的!因此,如果您在 .env 中看到 %21,它实际上可能是一个 ! 符号。