This comment outlines a working way to login with the new CSRF token:

  1. POST to /rest/user/login (nothing in headers). Construct the $cookie from session name + id
  2. GET to /services/session/token (include $cookie in the headers). Save the $token returned.
  3. Include $cookie and $token in the headers of subsequent requests of a logged in user.

That sequence works even though the first POST happens without sending the token. (The documentation suggests that the token should be used for any POST requests, which does not work in this case.)

What is a working sequence of HTTP requests to register a new user account? I'm looking for what requests to make in what order - not implementation code.

UPDATE: To be clear, I'm not looking for the login sequence. I need a sequence of requests (similar to login example above) that allow a new user to *register* their account.

Failed Attempt with system/connect:

1. GET:services/session/token

2. POST:system/connect
      Content-Type: application/json
      Accepts: application/json

3. POST:user/register
      Content-Type: application/json
      Accepts: application/json
      X-CSRF-Token: [token]
      Cookie: [session_name]=[sessid]
      Body: {
               "mail":"[email protected]"

The Drupal user is created correctly, but the request in step 3. times out.


1 Answer 1


Edit: to address the change in the question

I'm looking for what requests to make in what order - not implementation code

You can safely ignore the actual code implementation below - the order of the requests remains the same. In fact, exactly the same as in your original question.

If you're already making requests in the order that you've outlined, you needn't do anything more except provide an actual implementation. I'll leave the code in as an example, and so you can see exactly what order the requests need to be made in. I've stuck some numbering in to make it more obvious; the requests are denoted by 1, 2 & 3.

This is a basic PHP (i.e. non-Drupal) example...

First off make a generic function for sending your requests:

function send_request($url, array $post_array = array(), $cookie = NULL, $token = NULL) {
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_USERAGENT, 'googlebot');
  //curl_setopt($ch, CURLOPT_VERBOSE, $post_array);

  if (!empty($post_array)) {
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_array);

  if ($cookie) {
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);

  if ($token) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-CSRF-Token: ' . $token));

  $result = curl_exec($ch);

  return $result;

1. Then make your first call to log the user in:

// Login.
$data = array(
  'username' => 'user',
  'password' => 'password',

$result = send_request("http://server/endpoint/user/login.json", $data);

try {
  $result = json_decode($result);
catch (Exception $e) {
  die('Login failed: ' . $e->getMessage());

Next get the session name and ID, creating your cookie string to send with subsequent requests:

$session_id = $result->sessid;
$session_name = $result->session_name;    
$cookie = $session_name . '=' . $session_id;

2. Then get a CSRF token, making sure to pass the cookie along:

$token = send_request("http://server/services/session/token", array(), $cookie);

3. Finally you can perform your request to the endpoint you're actually interested in. The cookie and token are injected by the send_request() function.

$user = array(
  'mail' => '[email protected]',
  'name' => 'name',
  // Other relevant properties/fields.

$result = send_request('http://server/endpoint/user', $user, $cookie, $token);

I haven't tested the user creation endpoint so that might not be the exact structure it needs, but checking the responses for errors should let you know exactly what it's after quite quickly. I get the impression from your question that you're mainly interested in the steps leading up to that last request anyway.

The above is adapted from a basic test script I use, for a production environment you'll want to add more error/sanity checking in there. And the functionality is crying out to be wrapped in a class, and be extended to support PUT/DELETE, but I'll leave that to you :)

  • Thanks for the PHP login example, @Clive. I'm actually trying to figure out user/register in particular. I'll be working in another language so I'm just looking for the HTTP requests. Jul 22, 2013 at 18:15
  • @JoeBeuckman OK...that would be a naked POST to the login URL, followed by a GET to the token URL with the cookie string as part of the request, followed by a POST to the user endpoint containing the cookie, the X-CSRF-Token header, and the account data. There's not really anything more that I can say, that workflow just needs to be implemented in the language of your choice. The above PHP should make porting it pretty easy (if you're familiary with php, of course). BTW user/register is a synonym for user/create so you can use them interchangably
    – Clive
    Jul 23, 2013 at 15:48
  • Actually, I'm not really sure how this doesn't answer your question, could you explain why the implicit order described above is insufficient for your needs? Are you looking for extra info that isn't listed in the question?
    – Clive
    Jul 23, 2013 at 15:54
  • The sequence you provided is for login and my question asks about register. Good to know that user/register is a synonym for user/create although they seem like they should be different to me. I'm looking for a way a new user can create their account. They aren't logged in and can't log in until they have an account. I assumed that was user/register and I don't understand how to create an account while not logged in. Jul 23, 2013 at 16:33
  • 2
    Ahh ok, sorry I didn't get that. You probably need to replace the call to login with system/connect, I think that'll get you the session info without logging in. Then proceed as normal with steps 2/3 above. Just on mobile so can't check it out at the mo, will take a proper look later on
    – Clive
    Jul 23, 2013 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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