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.

  • Your tip about enabling application/x-www-form-urlencoded saved me a bunch of time. – drewish Apr 24 '12 at 21:06
up vote 1 down vote accepted

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.

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).

  • Yes, Session Auth. It appears to be the only option. I double-checked today to make sure it was enabled. I see the user object successfully, every time I test. I have been retrieving and sending the SESSID in the PHP CURLOPT parameters as shown in Michael Cole's original post linked above. Besides sending it as a cookie in the CURL params I have also tried sending it as a URL querystring argument. – Paul S. Jan 16 '12 at 22:00
  • I have updated my original posting with current code and explanation. – Paul S. Jan 16 '12 at 22:27
  • I ran into this problem a few days ago, what I did was FIRST use the system/connect call to retrieve a SESSID (eventhough it's from an anonymous user), THEN login (sending this SESSID as POST argument), and FINALLY retrieve a node (sending the SESSID through GET). Try this and let me know. – rafaelcr Jan 17 '12 at 23:41
  • If this does not work... double check if an authenticated user has permissions to view nodes... I know it sounds stupid but this could be the real problem. – rafaelcr Jan 17 '12 at 23:41
  • sorry for the long delay in response. I finally got to work on this again this week. I discovered that the problem was my login went to http: // www.mydomain.com but my node retrieval was directed to http: // mydomain.com. Once I made those match, it worked. – Paul S. Jul 18 '12 at 18:38

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.