Question

I am new to Drupal. My goal is to use it for staff to manage their own content, then retrieve their content from nodes via REST to the existing public website.

Using Drupal 7.10, Services 3. Drupal resides in a subdirectory, not at the site root, if that matters. An endpoint named "rest" has been created for the REST server. Anonymous access is not desirable, so a Drupal user has been created for authenticated access requests.

I am building a PHP client based on a post by MichaelCole for auth access. It seems to be talking to the REST server, as at first I was seeing our Drupal site theme along with a Drupal error in my generic PHP page.

At this time I am only trying to log in as my service user, so just the login.php code is running on my page.

PHP is returning this:

RESPONSE: string(0) "" Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /path-to-my-page/test-drupal-rest.php:36 Stack trace: #0 /path-to-my-page/test- drupal-rest.php(36): SimpleXMLElement->__construct('') #1 {main} thrown in /path-to-my- page/test-drupal-rest.php on line 36

Line 36 is:

$xml = new SimpleXMLElement($response);

If I just put the full service URL into my browser ( http://www.mydomain.com/drupal-folder/rest/user/login.xml ), I get (XML broken with spaces for display here):

< ? xml version="1.0" encoding="utf-8"?> < result/>

I am out of ideas. Can you help?

EDIT/UPDATE: I went into Administration » Structure » Services and discovered that "application/x-www-form-urlencoded " under Request Parsing was disabled. I enabled that, and my requests started going through. However, even though it obviously recognizes my user auth, I still cannot retrieve a node.

=====================

Edit/Update 2012-01-16 15:10 : Here is my current code, based on MichaelCole's code and modified for my workflow and goal. It does not retrieve the node content. The failure appears to be somewhere in the sending of the session authentication with the node request. Logging in always works properly and I always receive my XML user object.

loginToDrupal();

$service_url = "http://mysite.com/drupal-folder/resttest/node/10.xml";

$session_cookie = file_get_contents('session_cookie.txt');

print "Ready to send cURL to $service_url";

// set up the request
$curl = curl_init($service_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // have curl_exec return a string
curl_setopt($curl, CURLOPT_COOKIE, "$session_cookie"); // use the previously saved session
curl_setopt($curl, CURLOPT_HTTPGET, true); //do a GET ^^^^added by me...
curl_setopt($curl, CURLOPT_VERBOSE, true); // output to command line

$response = curl_exec($curl);
curl_close($curl);
print "\n<br />RESPONSE:\n";
var_dump($response);

logoutOfDrupal();

//=======================================================================


function loginToDrupal()
    {
    $service_url = 'http://www.mysite.com/drupal-folder/rest/user/login.xml'; // .xml asks for xml data in response
    $post_data = array(
          'username' => 'myusername',
          'password' => 'mypass',
        );
    $post_data = http_build_query($post_data, '', '&'); // Format post data as application/x-www-form-urlencoded

    // set up the request
    $curl = curl_init($service_url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // have curl_exec return a string
    curl_setopt($curl, CURLOPT_POST, true);             // do a POST
    curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); // POST this data

    // make the request
    curl_setopt($curl, CURLOPT_VERBOSE, true); // output to command line
    $response = curl_exec($curl);
    curl_close($curl);
    print "\n<br />RESPONSE:\n";
    var_dump($response);

    // parse the response
    $xml = new SimpleXMLElement($response);
    $session_cookie = $xml->session_name .'='. $xml->sessid;

    file_put_contents('session_cookie.txt', $session_cookie);

    if($xml->sessid!="")
        {
        print "login successful, session $xml->sessid <br />";
        }
    else
        {
        print "Login appears to have failed.";
        }
    }

//========================================================================================

function logoutOfDrupal()
    {
    print "\n<br />Logging out...<br />";
    $service_url = 'http://mysite.com/drupal-folder/rest/user/logout';
    $session_cookie = file_get_contents('session_cookie.txt');

    // set up the request
    $curl = curl_init($service_url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  // have curl_exec return a string
    curl_setopt($curl, CURLOPT_COOKIE, "$session_cookie"); // use the previously saved session
    curl_setopt($curl, CURLOPT_POST, true);             // do a POST
    curl_setopt($curl, CURLOPT_POSTFIELDS, ""); // POST this data

    // make the request
    curl_setopt($curl, CURLOPT_VERBOSE, true); // output to command line
    $response = curl_exec($curl);
    curl_close($curl);
    print "\n<br />RESPONSE:\n";
    var_dump($response);
    print "\n<br />reached end of function logoutOfDrupal()<br />";
    }

The debug print call after the loginToDrupal() function always returns XML like this:

< ?xml version="1.0" encoding="utf-8"? >< result >< sessid >AU7yWNWPXxORI2DsdJVegdreg2F9rYQxy90dAB5px2s< /sessid >< session_name >SESSd9af11d86664849a8dcda2d6c4af3580< /session_name >< user >< uid >11< /uid >< name >myuser< /name >< mail >me@mysite.com< /mail >< theme >< /theme >< signature >< /signature >< signature_format >filtered_html< /signature_format >< created >1326401726< /created >< access >1326746687< /access >< login >1326748351< /login >< status >1< /status >< timezone >America/Denver< /timezone >< language >< /language >< picture/ >< init >me@mysite.com< /init >< data >< contact >1< /contact >< /data >< roles is_array="true" >< item >authenticated user< /item >< /roles >< rdf_mapping >< rdftype is_array="true" >< item >sioc:UserAccount< /item >< /rdftype >< name >< predicates is_array="true" >< item >foaf:name< /item >< /predicates >< /name >< homepage >< predicates is_array="true" >< item >foaf:page< /item >< /predicates >< type >rel< /type >< /homepage >< /rdf_mapping >< /user >< /result >

Even though it clearly returns a successful user object, the code above returns an empty XML string every time I try to retrieve the node.

Was it helpful?

Solution

Today I discovered a simple problem with my sample code: In the node retrieval, the URL is:

$service_url = "http://mysite.com/drupal-folder/resttest/node/10.xml";

whereas in the login function, it is:

$service_url = 'http://**www**.mysite.com/drupal-folder/rest/user/login.xml';

I changed it so that all URLs point to www.mysite.com, and I can now retrieve a node as an authenticated user.

OTHER TIPS

So you're saying that you logged in as a user correctly. Which auth method are you using? Session Authentication? If so, the login response should return a user object, from which you need to take the SESSID, store it on your application/other website/client, and use it whenever you need to retrieve a node. You have to send the SESSID as another parameter in your node retrieve request alongside the nid (yes, every time).

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top