Doing some experiments with my XML-RPC code today, I noticed that calling "user.logout" seemed to be having no effect. I was able to create an authenticated session with "user.login", send some requests with it, destroy it with "user.logout", then continue to send requests with it. Looking in the sessions table, the session was still there and had the authenticated UID. I am requiring the session ID be passed as the first parameter of all XML-RPC calls.
Looking at user_service_logout in user_service.module, it seems to be destroying the temporary session generated by Drupal, not the session ID passed in as the first parameter of my XML-RPC call.
My quick hack to fix this is to call session_id() in services_session_load to set the session ID to the one passed into XML-RPC, then call session_id() again in services_session_unload() to set it back to the original session ID. With this change, when user_service_logout is called, it has the XML-RPC session ID set, and so logs that one out.
If that sounds like the right fix, I'd be happy to submit my patch; it's very simple.
Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | services_logout.patch | 803 bytes | scottgifford |
Comments
Comment #1
marcingy commentedHey post your patch and if we find an issue then we have a ready made solution. And you have investigated the issue and your proposed solution sounds good however being able to see the code will be helpful in determining if the approach is incorrect.
Marc
Comment #2
scottgifford commentedComment #3
scottgifford commentedSure, here it is.
Comment #4
mattman commentedI'm changing this to version 6.x dev because this issue applies to the current HEAD as well.
For some reason (of which I currently can't dig deeper) Drupal's session handling in bootstrap is not killing the session (assuming that Services want's Drupal to handle it).
It would seem that since calls are initially assumed anonymous by Services (until authenticated), it might be a good idea on user.logout to explicitly call
sess_destroy_uid()orsess_destroy_sid()from session.inc.Does this make sense? Services is a service, it's not a user interacting via a web browser. Therefore, it seems as though it's "ok" to assume control of the sessions based on user logout actions.
Also, it would be an improvement for Services to manage it's own watchdog messages. Where currently, user_service_logout() uses.
watchdog('user', 'Session closed for %name.', array('%name' => theme('placeholder', $user->name)));Where it would be easier to troubleshoot if Services would log messages under it's own domain. Plus, using the theme() function is adding silly html code to the log - which is unnecessary. I don't need to see
<em>User Name</em>in the log.While I can't roll a patch right now, I thought I would mention these things since this thread is here.
Comment #5
dereks commentedPossible fix -
Hello - I've been struggling with this as well. It sounds like the problem is the mx.rpc.AbstractService already has a logout method, so the logout command isn't making it to this module at all. There is a snippet on this web page in the third full paragraph:
http://sray.squidpower.com/2007/08/28/flex-2-java-session-log-out/
I saw another similar page from Adobe, but I don't have the link.
It sounds like simply renaming the function would do the trick.
HTH,
Derek
Comment #6
scottgifford commentedIn my case at least, I can see from the logs that the correct function in Drupal is being called.
Comment #7
scottgifford commentedThat is, when I add an error_log statement to the function, which I did while debugging, I can see it being called in the logs.
Comment #8
dereks commentedI'm new to Drupal, but I've been using Flash and Flex for years. In my case it seems pretty clear that the mx.rpc.AbstractService is getting in the way. Perhaps there is more than one issue to address here?
In Flex I am seeing the following. My RemoteObject id="user", and login works correctly.
1. If I add parameters to the logout function (session id and hash, etc), flex throws an error saying no parameters are expected with the logout function.
2. If I trick the compiler by using this["user"].logout(hash, domain, timestamp,nonce,sessionid) instead of user.logout(hash, domain, timestamp,nonce,sessionid) -- it compiles, I get this error in the AbstractService:
ArgumentError: Error #1063: Argument count mismatch on mx.rpc::AbstractService/logout(). Expected 0, got 5.
I hope this helps.
Derek
Comment #9
sitron2 commentedhi dereks,
i dont think you issue has anything to do with this thread.
concerning your issue, snelson posted this in another thread:
For Flex reserved words, you can use the getOperation() method to call methods. So, since you can't do user.logout(), you do user.getOperation('logout').send(). Not as nice, but Flash/Flex really shouldn't have used "logout" as a method name.
where "user" should be replaced by your remoteconnection name. (and you can include the sessid as send(sessid))
Comment #10
dereks commentedThanks sitron2 - that worked, Yay!
Still working my way through this. Sorry if I posted to the wrong spot.
Comment #11
marcingy commentedSorry this has taken me a while to look at it, @scottgifford the patch worked prefectly. Commited in d5 and d6.
Comment #12
scottgifford commentedGreat, thanks!
Comment #13
marcingy commentedComment #14
rafalskalski commentedHi guys there is still something wrong with this ... I'm using services with amfphp and when i send logout user is still on "online" list i can connect from different browser and login again with this same credentials ... then i have 2 same users logged in simultaneously... is sort of late and i was working all day ... maybe i do something wrong ? any help ...
Comment #15
rafalskalski commentedok .... user_service_logout() - do not delete session from database
adding db_query('DELETE FROM {sessions} WHERE uid = %d', $user->uid); could help,
and ,
tell me if i think right i'm php programmer new to drupal and i know you guys have your own ways of doing things ... maybe accessing db form here is some sort of sacrilege and i don't want to cause some holly war so please help :)
Comment #16
marcingy commentedsession_destroy(); - destorys the current session and behaves as per drupal core (see the user_logout function in the user module). Plus in drupal multiple people can login using the same id at the same time. If you want to enforce this rule you would need to create a hook_user function of your own which performs the check for existing sessions when someone logs in.
Comment #17
kris digital commentedHi,
I spent some time now getting an error when logging out from a flash site when I was logged in in the backend at the same time. user_service_logout always killed the wrong session and gave an error "couldn't session_encode().." or something.
I (seem to have) fixed it by using
sess_destroy_uid($user->uid);instead of
session_destroy()in user_service_logout()
Thank's mattman for the hint!
Comment #18
bricef commentedSame issue in 7.x version.
Comment #19
manolo.cruces commentedHi,
I have an error with de logout service. When i need logout the user the system send me an error: FALSE (User is not logged in ...). But if i check de "sessions" table i can find this user.
Thanks.