algolia / scout-extended

Scout Extended: The Full Power of Algolia in Laravel
https://www.algolia.com/doc/framework-integration/laravel/getting-started/introduction-to-scout-extended/
MIT License
395 stars 84 forks source link

Forwarding client IP address #160

Open JayBizzle opened 5 years ago

JayBizzle commented 5 years ago

We currently have a very simple aggregate keyword search that works something like this...

$result = KeywordSearch::search($this->request->get('query'))
    ->with([
        'filters' => $this->buildFilter(),
    ])
    ->paginate(80);

We noticed that in the Algolia statistics, it looks there there is only one user of the search, but it turns out this is because we need to forward the users IP address.

The API docs say that you should do something like the following to forward the IP address, but how does this fit with our code above?

$ip = '94.228.178.246';
$client->setExtraHeader('X-Forwarded-For', $ip);

$results = $index->search('query', [
    'analytics' => true
]);

Thanks

nunomaduro commented 5 years ago

That's a great feature that currently it may be hard to use Scout Extendet.

Do you wanna work in a pull request for this with me? It idea may be resolve the client out of the container allowing people to bind their own implementation of the client: https://github.com/algolia/scout-extended/blob/f3475be9279dce705d438b74f97d91195f5e4409/src/Managers/EngineManager.php#L32.

JayBizzle commented 5 years ago

@nunomaduro Yes, would definitely be interested in working together on a solution to this issue 👍

nunomaduro commented 5 years ago

@JayBizzle Actually, it's already possible. Try this:

App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {

    $ip = '94.228.178.246';

    $options['headers']['X-Forwarded-For'] = $ip;

    return $algolia->search($query, $options);
})->get();
JayBizzle commented 5 years ago

Thanks for the suggestion.

I have just tested that and it returns the following error

Algolia\AlgoliaSearch\Exceptions\BadRequestException 
Unknown parameter: headers

Error thrown on line 199 of vendor/algolia/algoliasearch-client-php/src/RetryStrategy/ApiWrapper.php

188.             throw new RetriableException(
189.                 'An internal server error occurred on '.$request->getUri()->getHost(),
190.                 $statusCode
191.             );
192.         }
193.
194.         $responseArray = Helpers::json_decode($body, true);
195.
196.         if (404 == $statusCode) {
197.             throw new NotFoundException($responseArray['message'], $statusCode);
198.         } elseif ($statusCode >= 400) {
199.             throw new BadRequestException($responseArray['message'], $statusCode);
200.         } elseif (2 != (int) ($statusCode / 100)) {
201.             throw new AlgoliaException($statusCode.': '.$body, $statusCode);
202.         }
203.
204.         return $responseArray;
nunomaduro commented 5 years ago

cc @julienbourdeau. It's a not allowed header in php X-Forwarded-For?

JayBizzle commented 5 years ago

Any progress on this?

Thanks

nunomaduro commented 5 years ago

@JayBizzle Sorry for the late response.

Try like this:

App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {

    $options['X-Forwarded-For'] = $ip;

    return $algolia->search($query, $options);
})->get();
JayBizzle commented 5 years ago

Awesome, looks like that solution is working. Thanks 👍

JayBizzle commented 5 years ago

Just as an FYI

If you do the following with paginate() rather than get(), no matter what value you pass the paginate() method, you ALWAYS get 20 results

App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {

    $options['X-Forwarded-For'] = $ip;

    return $algolia->search($query, $options);
})->paginate(80);

All the pagination values like perPage will be correct, but there will actually be only 20 results in the Collection.

Not sure why? Perhaps i need to pass something to $options in the callback?

nunomaduro commented 5 years ago

I am not sure buddy, can you try to debug it?

JayBizzle commented 5 years ago

Yes, we have it on our list to look into when we have some spare time, just on with other projects at the moment 👍

JayBizzle commented 5 years ago

Had a chance to look into this a little further. I don't particularly think this is a bug, but it is a bit awkward how the code has to be put together to get it to work as expected...this is what works...

$options = [
    'X-Forwarded-For' => $ip,
    'hitsPerPage' => 80,
];

App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {
    return $algolia->search($query, $options);
})->paginate(80);

We have to pass the hitsPerPage parameter to the callback as well as pass it to the paginate method. Can't see a way to make this any cleaner at the moment, but at least it works 😕

nunomaduro commented 5 years ago

In your example, the $options is being ignored:

$options = [
    'X-Forwarded-For' => $ip,
    'hitsPerPage' => 80,
];