Elasticsearch API key & PHP
When you enable XPACK security in Elasticsearch, your clients (my website in this case) requires authentication to be setup. If you do not setup proper authentication, you will get similar errors.
Elastic\Elasticsearch\Exception\ClientResponseException
401 Unauthorized:
{
"error": {
"root_cause": [
{
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/index/_search]",
"header": { "WWW-Authenticate": ["Basic realm=\"security\" charset=\"UTF-8\"", "ApiKey"] }
}
],
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/index/_search]",
"header": { "WWW-Authenticate": ["Basic realm=\"security\" charset=\"UTF-8\"", "ApiKey"] }
},
"status": 401
}
I found two ways to solve this, I could setup either one of these:
- basic authentication
- API Key
Basic Authentication
Use this guide to generate an username / password combination, default username is elastic
Using Elastic Search client:
$client = ClientBuilder::create()
->setBasicAuthentication('<username>', '<password>')
->build();
If you use configuration files, you can set up the following key basicAuthentication
in your node pool
'hosts' => [
localhost:9200'
],
'basicAuthentication' => [
'<username>',
'<password>'
]
Using babenkoivan/elastic-client
If you use babenkoivan/elastic-client (I use it for Laravel), publish the config file and go to elastic.client.php
and add it under your connections
<?php declare(strict_types=1);
return [
'default' => env('ELASTIC_CONNECTION', 'default'),
'connections' => [
'default' => [
'hosts' => [
env('SCOUT_ELASTIC_HOST', 'localhost:9200'),
],
'basicAuthentication' => [
'<username>',
'<password>'
]
],
],
];
API Key
To generate an API key, you will still require the username & password from basic authentication. Then you can generate an API key first using either cURL or Kibana. I used this query:
curl --location --request POST 'http://<username>:<password>@localhost:9200/_security/api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "php-client"
}'
This returned a response with the api_key
and id
key
{
"id": "<id>",
"name": "php-client",
"api_key": "<api-key>",
"encoded": "<encoded>"
}
Using Elastic Search
$client = ClientBuilder::create()
->setApiKey('<id>', '<api_key>')
->build();
Using babenkoivan/elastic-client
If you use babenkoivan/elastic-client, publish the config file and go to elastic.client.php
and add it under your connections to use the encoded
key - it includes both id and api key.
<?php declare(strict_types=1);
return [
'default' => env('ELASTIC_CONNECTION', 'default'),
'connections' => [
'default' => [
'hosts' => [
env('SCOUT_ELASTIC_HOST', 'localhost:9200'),
],
'apiKey' => [
'<encoded>
]
],
],
];