I have Services 3.4 where some changes to how they do things precipitate changes we need to do to things.

Two I'm looking at right now are the below:

  1. Services 3.4 prevents cross site request forgery by asking for an extra header param in the login and register calls. See #2013781: need Change Record for changes CSRF - 'CSRF validation failed' since update to 3.4, where comment #4 outlines how to get the session token first and then add it to the header.
  2. Services 3.4 seems to change some of the params sent over. A few I found right off the bat were from login (I am so worried that once login works, other params will be strange too!). "username" is now "name", and "password" is now "pass". Crazy, crazy services 3.4

I'm trying to fix my deployment setup but lets get all the patches to catch up Deploy to Services 3.4 here. Or let me know if we already have a place for those.

En Taro Adun

Comments

diwant’s picture

Here's what my login code looks like now, and it looks like it is able to move beyond login.

  $logout_url = $this->service->config['url'] . '/user/logout';

  // .. I added this code to fetch the CSRF token

  $csrf_token_url = $this->service->config['url'] . '/services/session/token';
  $csrf_token = drupal_http_request($csrf_token_url, array(
      'method' => 'GET',
  ));

  // .. I modified the keys in the data below and added the token fetched above to the header under the right header key ('X-CSRF-Token')
  
  $options = array(
        'method' => 'POST',
        'headers' => array('Content-Type' => 'application/json', 'X-CSRF-Token'=>$csrf_token),
        'data' => drupal_json_encode(array(
              'name' => $this->config['username'],
              'pass' => $this->config['password'],
        )),
  );

This is near line 32 of deploy/plugins/DeployAuthenticatorSession.inc

diwant’s picture

Scratch that. This works better, I've pasted the entire if block so you can compare with yours. This is in 'deploy/plugins/DeployAuthenticatorSession.inc' and I've left the line numbers there

  59       if ($response_data['session_name'] && $response_data['sessid']) {
  60         $this->service->config['headers']['Cookie'] = $response_data['session_name'] . "=" . $response_data['sessid'] . ";";
// NEW CSRF STUFF STARTS HERE
// 1. Fetch the token providing the cookie in the header
  61         $csrf_token_url = substr($this->service->config['url'],0,-5) . '/session/token';
  62         $csrf_token_response = drupal_http_request($csrf_token_url, array(
  63          'method' => 'GET',  
  64          'headers' => array('Cookie'=>$this->service->config['headers']['Cookie']),
  65         ));
// Set the token in the config so it is used in all future requests
  66         $this->service->config['headers']['X-CSRF-Token'] = $csrf_token_response->data;
  67       } else {
  68         throw new DeployAuthenticationException(t("No session was returned from the authentication request."));
  69       }

I think this fixes that issue. Let me know if this is the right approach.

rob_johnston’s picture

The patch at comment #2 in #2017767: Error and response with 405 code when try to deploy node solves the problem as well. Some lines of the code are identical to what you provided here, so lets compare, contrast, and discuss which is better.

dixon_’s picture

Version: 7.x-2.0-alpha1 » 7.x-2.x-dev
Status: Active » Fixed

The issue itself is fixed. If there are substantial improvements that can be made, please reopen and we can discuss :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.