scout-extended icon indicating copy to clipboard operation
scout-extended copied to clipboard

Forwarding client IP address

Open JayBizzle opened this issue 6 years ago • 13 comments
trafficstars

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

JayBizzle avatar Mar 18 '19 10:03 JayBizzle

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.

nunomaduro avatar Mar 18 '19 11:03 nunomaduro

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

JayBizzle avatar Mar 18 '19 11:03 JayBizzle

@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();

nunomaduro avatar Mar 18 '19 11:03 nunomaduro

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;

JayBizzle avatar Mar 18 '19 11:03 JayBizzle

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

nunomaduro avatar Mar 18 '19 11:03 nunomaduro

Any progress on this?

Thanks

JayBizzle avatar Apr 09 '19 19:04 JayBizzle

@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();

nunomaduro avatar Apr 10 '19 07:04 nunomaduro

Awesome, looks like that solution is working. Thanks 👍

JayBizzle avatar Apr 10 '19 08:04 JayBizzle

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?

JayBizzle avatar Apr 17 '19 11:04 JayBizzle

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

nunomaduro avatar Apr 17 '19 11:04 nunomaduro

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 avatar Apr 17 '19 11:04 JayBizzle

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 😕

JayBizzle avatar Apr 17 '19 19:04 JayBizzle

In your example, the $options is being ignored:

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

nunomaduro avatar Apr 18 '19 15:04 nunomaduro