1

I have been having a problem persisting the authenticated session after a successful registration using Services 7.x.3.11 in Drupal 7.

I've sort of solved that issue by commenting out the call to _services_controller_execute_preserve_user_switch_anonymous() inside of sites\all\modules\services\includes\services.runtime.inc. The file's comments read:

As authentication methods should authenticate user themselves changing global $user variable we preserve incoming session authenticated user and his session so changes made by authentication do not interfere.

Aside the grammer, I do not understand the purpose of this method nor how Services authentication works and integrates with Drupal's core. Can anyone explain why this is necessary for Services to honor Drupal's roles and permissions.

1

The user register action (which is essentially just an alias of the user.create resource) executes the user register form. Doing so affects the global $user object, which overwrites any existing $user object. Other resources related to the user will also do the same thing.

This is undesirable, as it replaces the global user that you're using to authenticate against the endpoint. So the Services module saves your session before executing any callbacks, and restores it afterwards. This ensures the integrity of the original session.

I think the misunderstanding is simply that you're expecting the user register resource to automatically invalidate the current session, and replace it with a session for the newly created user. I can't see anything in the code that would suggest that's supposed to happen, and it makes sense that it wouldn't...

Imagine your app needed to register 10 users in a batch; if your session was invalidated each time you made a call to user.register, and replaced with a session for the new user, you'd have to logout and potentially re-authenticate before each subsequent registration. Not an ideal situation to be in.

  • i'm expecting to keep the same session but just change the user object from anonymous to authenticated and related user data. Eitherway, it does not seem that a session is created at all here. My dblog reports show the user object passed around but ALWAYS as an anonymous user except for within the Core User module at user_login_finalize. Then I'm assuming the drupal_session_regenerate within removes the authenticated session as well. – E.A.T Dec 21 '14 at 22:23
  • Additionally @Clive, it appears these functions happen in the incorrect order. Essentially, _services_controller_execute_restore_user() overwrites the newly authenticated user with the 'original' anonymous user during register.json – E.A.T Dec 21 '14 at 23:01
  • Yes that's the expected behaviour. The original user is restored, even if that user is anonymous. By design, the user register resource is not supposed to log the newly created user in. It just creates it. There's no bug here, your expectations are just wrong. Once you accept that the Services module is not supposed to log the newly created user in, in fact the opposite, you'll be able to move on with your development – Clive Dec 22 '14 at 8:15
  • Accepted @clive... but so many tutorials and drupalgap's submodule with logintoboggan do at least make that claim it's a working feature. – E.A.T Dec 22 '14 at 10:02
  • It's weird that they make that claim, when you consider that they couldn't affect the operation of the Services module without changing its code, and it's plain-as-day what the Services module is trying to do. Definitely a mistake on the part of the tutorials' authors if they're making such claims (in my opinion anyway) – Clive Dec 22 '14 at 10:06
0

I know this is old but just for the record in case someone else came to the same problem, Drupal Services are preserving the user session who originally requested the service resource and restoring it after fulfilling the requested service resource. This is intentionally desired as long as the resource used will not login or log out the customers in drupal site.

An exception to this is dealing with other login provider like LDAP or Social Login through services, Thus the added service definition need to authenticate the user and log him in so he can resume using the other services.

Solution to this is to include the "login" word in your service call back definition, as this will grantee that drupal will keep the session that you created and consider it as valid session.

An example is as below for service definition

$definition['my_module']['actions']['connect'] = array(
'help' => 'Services login using my_module_logic ',
  // Please note that login is mandatory in the name of call back 
  // this will allow drupal to preserve the session that we get here
  // check _services_controller_execute_preserve_user_switch_anonymous
'callback' => 'services_my_module_login',
'args' => array(
 array(
    'name' => 'provider',
    'type' => 'string',
    'description' => 'A valid my_module login provider ',
    'source' => 'data',
    'optional' => FALSE,
  ),
),
'access callback' => 'services_access_menu',
);

You can get more information by checking the code here

_services_controller_execute_restore_user    

_services_controller_execute_preserve_user_switch_anonymous

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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