When a session is established using Services, a client intending to do modifying actions must request a CSRF token which is then included in subsequent requests. The Services module provides the path /services/session/token which returns the token for the session. Deploy currently grabs this token but uses hard coded assumptions:

  1. That the endpoint starts at the root of the domain (i.e. not in a subdirectory).
  2. That the path is /services/session/token

This means that Drupal installations installed in subdirectories, e.g. example.com/mydrupal cannot be used as endpoints. I found this to be annoying when doing testing as I did not want to setup a new subdomain or port on the web server.

The relevant code are lines 64 - 90 of plugins/DeployAuthenticatorSession.inc.

I couldn't think of a good way to automatically determine the proper URL, so making it configurable is the next best option. Since it the authenticator that logs in and grabs the token, it makes sense to me to add a form field for specifying the CSRF token request URL as part of the authenticators configuration. This creates some minor user experience issues as site builders need to enter one URL for the CSRF token and another URL in the Service config for the API endpoint.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

CalebD’s picture

Attached is a patch which adds a form field to the session authenticator for the token CSRF URL. It also provides an update function to update existing endpoints. I also adjusted the authentication config for tests, but haven't run the tests.

runeasgar’s picture

For clarity, right now if you are trying to connect to an endpoint that is in a subdirectory (localhost/whatever) the CSRF request will fail, because the $token_url is formed using $parts['host'], and the subdirectory ends up in $parts['path'] - which isn't used to form $token_url.

I encountered this issue while prototyping Deployment locally and had to dig through the code to find a way to fix it.

Does this patch resolve that issue?

thtas’s picture

@runeasgar yes it does.

Good patch - but may need to be re-rolled for later version of deploy

thtas’s picture

Here is a patch against 7.x-2.0-alpha2

jneubert’s picture

Re-rolled against 7.x-2.0-alpha3 - worked for me. Not yet tested extensively.

Viacom’s picture

Edit: sorry, logged in on the corporate account. Reposting.

reevo’s picture

I've been looking into this issue as am working on a site which lives under a subdirectory, however have discovered as part of my investigations that the token is actually returned as part of the response to the login request, which makes the additional 'services/session/token' request unnecessary:


$response_data = Array
(
    [sessid] => XXXXXXXXXXX
    [session_name] => XXXXXXXXXXX
    [token] => XXXXXXXXXXX
    [user] => Array()
)

And here it is in Services:

http://cgit.drupalcode.org/services/tree/resources/user_resource.inc?h=7...

edit: I'm not functioning properly today. Issue is addressed in #2388119: Get CSRF token from /user/login endpoint

mrmikedewolf’s picture

Here is a much more lightweight alternative. Just provide an alter hook.

skwashd’s picture

Status: Needs review » Postponed
Related issues: +#2388119: Get CSRF token from /user/login endpoint

I've reviewed this issue and #2388119: Get CSRF token from /user/login endpoint. I am marking this as postponed with a high probability of it being closed and marked as wontfix in favour of #2388119.

CoderBrandon’s picture

Rerolled #8 to apply to version 7.x-2.0-beta2.