phpgoogle-mapscurlgoogle-geolocation

Obtaining correct response from Google Geolocation API for MAC Address, PHP/JSON


I am currently developing a web portal to make use of the Google Geo-location API, specifically for MAC addresses.

I am using PHP and cURL to send a request for the API, decoding the returned JSON from google and for testing purposes, echoing the results.

The code I currently have successfully submits the request to Google's API and receives a result with no errors.

The problem I have is that the location results returned never relate to the location of the MAC address but always to the IP address used to send the request. The accuracy number is also always very high (inaccurate).

I have tested this using the suggested google input given at the address:

https://developers.google.com/maps/documentation/geolocation/intro#sample-requests

I can reliably alter the result returned by the API by using a VPN. I have also ensured my requests include 'considerIP' to be false. If no geolocation data is found the API should return a 404 error however I always get 200 codes with results.

From what I can see my cURL request is correct and I am at a total loss as to why the API returns information about my IP address when using their own suggested example.

Code shown below:

function askGoogle(){
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "https://www.googleapis.com/geolocation/v1/geolocate?key=[MYAPIKEY]");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $JSONArray = array (
        'considerIp' => 'false',
        'wifiAccessPoints' => 
            array (
                0 => 
                array (
                    'macAddress' => '00:25:9c:cf:1c:ac',
                ),
            1 => 
                array (
                    'macAddress' => '00:25:9c:cf:1c:ad',
                ),
            ),
    );

    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($JSONArray));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    $headers = array();
    $headers[] = "Content-Type: application/json";
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/json", "Content-Length: 0"));

    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "The curl completion is ".$httpCode."<br>";

    $message =  json_decode($result, true); //converts the returned JSON message into an array.

    print_r(array_values($message));
    echo "<br>";

    curl_close ($ch);
}

Solution

  • I got your code working. I believe the two reasons your request was returning the default ip-based response from the API is that you were using http_build_query on the array instead of json_encode, and because the content length in the header was 0 instead of the string length of the json payload.

    function askGoogle()
    {
        $ch = curl_init();
    
        curl_setopt(
            $ch,
            CURLOPT_URL,
            "https://www.googleapis.com/geolocation/v1/geolocate?key=[MYAPIKEY]"
        );
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
        $payloadArray = [
            'considerIp' => false,
            'wifiAccessPoints' => [
                [
                    'macAddress'         => '00:25:9c:cf:1c:ac',
                    "signalStrength"     => -25,
                    "signalToNoiseRatio" => -101
                ],
                [
                    'macAddress'         => '00:25:9c:cf:1c:ad',
                    "signalStrength"     => -25,
                    "signalToNoiseRatio" => -101
                ],
            ],
        ];
    
        $payloadJson = json_encode($payloadArray);
    
        curl_setopt(
            $ch,
            CURLOPT_HTTPHEADER,
            ["Content-type: application/json", "Content-Length: ".strlen($payloadJson)]
        );
    
    
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJson);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    
    
    
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }
    
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        echo "The curl completion is ".$httpCode."<br>";
    
        $message =  json_decode($result, true); //converts the returned JSON message into an array.
    
        print_r($message);
        echo "<br>";
    
        curl_close($ch);
    }
    
    askGoogle();