0

I'm trying to use the SPtrans API (http://www.sptrans.com.br/desenvolvedores/APIOlhoVivo.aspx), which is supposed to provide public transport information for the Sao Paulo (Brazil) area.

I'm trying to get in using PHP and curl.

I'm able to put in the requests and can authenticate myself (with a post request to /Login/Autenticar?token={token}. The post request returns a 'true' (and only a 'true'). (It seems that I need to put the token both as a GET and a POST.)

However, if I then put in an information (GET) request, for example to /Linha/Buscar?termosBusca={termosBusca}, I get a consistent return of "Authorization has been denied for this request." message.

You can see this (not) working at:

http://00qq.com/sptrans/index.php

Any thoughts or ideas on this would be extremely helpful.

Here's the code that picks up the data:

    function getResult($accesspoint, $page, $postData, $post = true) {
    $ch = curl_init();  

    $t = http_build_query($postData);

    $url = $accesspoint.$page."?".$t;

    curl_setopt($ch, CURLOPT_URL, $url);  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  

    if ($post == true) {
        curl_setopt($ch, CURLOPT_POST, true);  
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);  
    }
    curl_setopt($ch, CURLOPT_HEADER, 0);  

    $output = curl_exec($ch);  

    curl_close($ch);  

    $output = object_to_array(json_decode($output));    

    return $output;
}

Update

@chesterbr put me on the right track: I had to create, collect and store cookies upon authentication and then use those upon subsequent requests. Below is a proof of concept.

$site["sptrans"]["accesspoint"] = "http://api.olhovivo.sptrans.com.br/v0";
$site["sptrans"]["page"]["Login"] = "/Login/Autenticar";
$site["sptrans"]["page"]["Parada"] = "/Parada/Buscar";
$site["sptrans"]["page"]["Linha"] = "/Linha/Buscar";

$site["sptrans"]["token"] = ""; //This should contain your token.

error_reporting(E_ALL);
ini_set('display_errors', 1);


function object_to_array($data) {

    if (is_array($data) || is_object($data)) {
        $result = array();
        foreach ($data as $key => $value)
            $result[$key] = object_to_array($value);
        return $result;
    }

    return $data;

}


function getResult($accesspoint, $page, $postData, $cookie, $post = true) {
    $ch = curl_init();  

    $t = http_build_query($postData);

    $url = $accesspoint.$page."?".$t;

//  print $url."<br />";

    curl_setopt($ch, CURLOPT_URL, $url);  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
    curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookie);
    curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);
//  curl_setopt($ch, CURLOPT_COOKIESESSION, true);

    if ($post == true) {
        curl_setopt($ch, CURLOPT_POST, true);  
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);  
    }
    curl_setopt($ch, CURLOPT_HEADER, 0);  

    $output = curl_exec($ch);  

    curl_close($ch);  

    $output = object_to_array(json_decode($output));    

    return $output;
}


//Create a cookie for the duration of the page.
$ckfile = tempnam ("cache/cookies", "spt.");

print "Authentication<br />";
$postData["token"] = $site["sptrans"]["token"];
$output = getResult($site["sptrans"]["accesspoint"], $site["sptrans"]["page"]["Login"], $postData, $ckfile);
print_r ($output);
unset($postData);

print "<hr />";

print "Linha<br />";
$postData["termosBusca"] = "8000";
$output = getResult($site["sptrans"]["accesspoint"], $site["sptrans"]["page"]["Linha"], $postData, $ckfile, false);
print_r ($output);
unset($postData);

print "<hr />";

print "Parada<br />";
$postData["termosBusca"] = "Afonso";
$output = getResult($site["sptrans"]["accesspoint"], $site["sptrans"]["page"]["Parada"], $postData, $ckfile, false);
print_r ($output);
unset($postData);

print "<hr />";

//Delete the cookie
unlink($ckfile);

You can see this work at http://00qq.com/sptrans/index.php

MastaBaba
  • 1,085
  • 1
  • 12
  • 29

1 Answers1

1

The API requires you to store the cookies from the authentication call and include them in subsequent ones (otherwise, the server can't know those calls belong to the same session, since HTTP is stateless by default).

You can make that in PHP by configuring the cURL library as described in: https://stackoverflow.com/a/12885587. See also http://www.php.net/manual/en/function.curl-setopt.php for more information on such options (search for "COOKIE" options).

Community
  • 1
  • 1
chesterbr
  • 2,940
  • 3
  • 29
  • 26
  • Awesome. This put me on the right track. Updating my question now to include my crude proof of concept. – MastaBaba May 20 '14 at 23:36