Accessing positions from PHP: Illegal mix of collations

Albin Soft7 months ago

Hello

I cannot figure out why but I can access to positions using PostMan but when I try to replicate the HTTP Request from PHP I got this weird response.

if($curl = curl_init('https://demo3.traccar.org/api/positions')) {
    $headers = [];
    $headers[] = 'Authorization: Token RzBFA...';

    curl_setopt($curl, CURLOPT_COOKIEFILE, $path.'traccar.cookies');
    curl_setopt($curl, CURLOPT_COOKIEJAR,  $path.'traccar.cookies');
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0');
    curl_setopt($curl, CURLOPT_HTTPHEADER,     $headers);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_VERBOSE, 1);
    curl_setopt($curl, CURLINFO_HEADER_OUT, 1);
    $resp = curl_exec($curl);
    $info = curl_getinfo($curl);
    curl_close($curl);
    var_dump($info);
    var_dump($resp);
}

How can we solve it?

  • Albin
SwayDev7 months ago

Your code should work, I tested it using session cookies.

Check the authorization option you used, that could be where its failing.

Albin Soft7 months ago

Thanks,

Although I don´t see the connection between the authorization and the error (mix of collations)...

I changed $headers[] = 'Authorization: Token RzBFA...';
for $headers[] = 'Authorization: Bearer RzBFA...';
and worked.

I also regenerated the token but I am not sure it was part of the solution.

  • Albin
SwayDev7 months ago

There is not enough information shared by you for anyone to suggest where you got the "mix of collations" error. The collation error you saw may not even be related to this code.

When I tried your code, I received an error which is not a PHP generated error but is native to JAVA, That meant the CURL request worked and the API responded.

So I changed the $headers[] to use session cookie and it worked.

And from what you shared you, you corrected your $headers/authorization type by including 'Bearer' and it worked for you.

Albin Soft7 months ago

To be honest, I don´t understand how to make it work using session cookie.

I set curl options to work with cookies but I don´t know what more to do.

Any way, I focused on the clue that could be authorization related, and watching again PostMan I realize that, despite it ask for a token, the auth header is bearer. That's why I changed it.

Doing test and test, in some moment I saw a JSESSION cookie and I saw in API that there is also a session concept, even I found someone tring unsuccessfully to use it with the /api/socket endpoint... but I tried and it didn´t work too.

There aren´t samples of how it is supposed to work, is left to intuition. IMHO.

  • Albin
SwayDev7 months ago

Here is a very basic approach to using curl and getting the session cookie.

It's not a clean code, there may be some issue with the usage of trim()

$apiUrl = 'https://demo3.traccar.org/api/session';

$username = 'youremail@email.com';
$password = 'yourpassword';

$ch = curl_init($apiUrl);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "email=$username&password=$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 1); // Include response headers in the output

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'cURL error: ' . curl_error($ch);
}

curl_close($ch);

list($headers, $body) = explode("\r\n\r\n", $response, 2);

$headersArray = explode("\r\n", $headers);

foreach ($headersArray as $header) {
    if (strpos($header, 'Set-Cookie:') === 0) {
        $cookie = trim(substr($header, 11));
        // You can store or use the $cookie value as needed.
        break;
    }
}

echo $cookie;
echo $body; // This will be the actual API response body.

You can then use the $cookie in your code.

Albin Soft7 months ago

Thanks for continuing the conversation.

It makes sense to get the cookie from the server side, so we don´t expose the credentials in the client javascript.

But once I get that cookie, how can I use it in for the sockets?

Because I can send it to the browser with set_cookie but the cookie will be binded to my domain and the API is in another domain so the browser will not send it as a part of the wss connection.

  • Albin
SwayDev7 months ago

Deploy the API on the same domain, or implement a intermediate authentication script on the domain with websocket.