webtechnick / CakePHP-Facebook-Plugin

CakePHP Facebook Plugin
http://facebook.webtechnick.com
445 stars 138 forks source link

Facebook logout Session problem #107

Open Sanganabasu opened 11 years ago

Sanganabasu commented 11 years ago

I am using facebook helper for login button as below $this->facebook->login(array('redirect' => 'facebook_login', 'label' => 'sign in via facebook', 'id' => 'fb-login')). and for logout button as below $this->Facebook->logout(array('redirect' => array('controller' => 'users', 'action' => 'logout'), 'label' => 'Logout')). In logout action I am using this code $this->Auth->logout(); $this->redirect(Controller::referer());

So when i get login its showing old user logged data. Please help me how to overcome this..

aldeed commented 11 years ago

The plugin stores user data in Session. Before calling $this->Auth->logout() in your logout action, destroy the session:

$this->Session->destroy();

Or just

$this->Session->delete('FB');

Might work.

oidacra commented 11 years ago

Work for my.

danielsb commented 11 years ago

I need to use what @aldeed explained to make it work properly.

rightawayai commented 11 years ago

in my case If I do any of those suggested by @aldeed I cannot get used to login again, it shows that it is logged in but the session is not created

aldeed commented 11 years ago

@100marks: Hard to say what might be the problem without seeing some code. Are you able to post the code from your login and logout actions?

pennycoders commented 11 years ago

I have solved this by adding some extra code inside the _syncFacebookUser() function, inside ConnectComponent.php, after defining an array of user logout actions(actual function names, in the config file..

if(in_array($this->Controller->request['action'],Configure::read('Facebook.logout_actions'))){
$this->FB->destroySession(); if(Configure::read('debug')>0){ $this->Controller->log($this->Controller->request['action'],'-destroyed session!',"facebook"); } }

pennycoders commented 11 years ago

Please note that you could emulate the same logic inside the beforeFacebookLogin($user) callback...

aldeed commented 11 years ago

So the next time Connect->user() is called, uid will be unset as a result of destroySession(), which will cause it to delete the 'FB' session variable? Just making sure because at some point Session->delete('FB') will need to be called or the problem won't actually be fixed.

pennycoders commented 11 years ago

Well, this isn't about the 'FB' session variable, there's a session variable that's set by the facebook apy itself, it is something like $_SESSION['fbAPPTOKEN...'] (Don't recall the exact string afterwards, but if you'd do a pr($this->Session->read()) after logging out, you would see it, this way i just make sure it's deleted, otherwise, your users will always be logged in, regardless if they log back out. I thought it would be best to do it inside this plugin, because otherwise it wouldn't be a propper sollution to the problem.

Please let me know if it has worked for you.

aldeed commented 11 years ago

Interesting, @pennycoders, that is a different issue, but a good idea.

The original issue in this thread is that when you log in with FB, then log out of FB, then log in with a different FB user, the first FB user's data is still cached in the session 'FB' key. So you need to do $this->Session->delete('FB'); in your logout action. In this case, login and logout work fine, but the session data isn't updated.

The issue @pennycoders is fixing (I think) is that logging out with the normal site logout process doesn't log you out of FB, so you are immediately logged back in. Most people don't experience this issue because they display the FB logout button for users who logged in using FB. That button logs you out of Facebook and the site at the same time. But if you want to log out of only the site and not FB, I think deleting the fb_APPTOKEN during logout would work.

Ideally, both of these things should probably be done by the plugin.

pennycoders commented 11 years ago

No, actually the problem i was having @aldeed was that when i was using the facebook logout function, and afterwards was redirecting the users to my logout page, it was still logging them in, even though i had a facebook logout button in place. Regarding the FB Session var, that does get deleted, at least in my case. And no, just deleting fb_APPTOKEN wouldn't work to log the users out on the site only, due to the fact that the plugin checks for the facebook session, if it is open, and if yes, it just logs you in.. so by calling $this->FB->destroySession(); in the connectcomponent, you destroy that session, you prevent that from happening. See my comment above.

As far as your issue goes, you could put this inside the block i have posted above:

if(in_array($this->Controller->request['action'],Configure::read('Facebook.logout_actions'))){ $this->Controller->Session->delete('FB'); $this->FB->destroySession(); if(Configure::read('debug')>0){ $this->Controller->log($this->Controller->request['action'],'-destroyed session!',"facebook"); } } Also, please note that when using a custom session handler, and custom session settings in general, like a speciffic cookie name, the cookie always gets deleted.

Regards,

Alex.

aldeed commented 11 years ago

Ah, OK, I see. It's interesting that I have not experienced your problem and you have not experienced mine. Must be due to different settings elsewhere in our apps. In your last statement about custom session settings, are you saying that if I use a custom cookie name instead of the 'CAKEPHP' default, that the 'FB' user data won't remain in the session data after logout?

Are you planning to do a pull request to get your code added to the plugin? I think the code looks good, but I would probably use the component's $settings array to define logout_actions instead of the config file. Isn't that what CakePHP recommends?

pennycoders commented 11 years ago

no, what i am saying is that if you are planning on using a custom session handler, a cakephp one, it wouldn't work, nor does the CAKEPHP session cookie name work.. try it, and you'll see it gets deleted each and every time. That happens due to the fact that the facebook api starts a session all on it's own... (See lines 47-55 in Vendor/Facebook.php ).

Regarding the pull request.. well, i don't know if this would be something that everybody will need... I do like to think ahead when it comes to scalability, which is why i want to keep the benefits of being able to use a custom session handler, even on a shared environment.. Facebook themselves shouldn't do what they are doing, and i am a strong believer that they should NOT do what they are doing.. :) I mean, just because you must load your plugins in the booststrap.php file, which gets processed prior to many others, you can't do much to influence that, it might ruin your business's scalability.. simply because they want to encourage (as i see it) spaghetti-coding.. What if i want to use Redis or some other neat sessions storage engine? i can't do that of this happens.. What i did to prevent that, is this, inside the ConnectComponent, inside the initialize function, after defining $this->Controller, next line.

$this->Controller->Session->id($this->Controller->Cookie->read(Configure::read('Session.cookie')));

Also, regarding the place where i would consider appropiate to define the logout_actions, well...i like keeping the code flexible/versatile, so i'm never up for hardcoding stuff.. The more flexible/easy to migrate, the better. (What if you'd have to load-balance between multiple domains/machines/whatever? wouldn't you like to have all the configuration centralized? (i've even got the whole config array in a single file, just for that.

Please, let me know if there's anything i can help with.

Regards,

Alex.

aldeed commented 11 years ago

Thanks for your explanation. That makes sense. I haven't used this plugin for anything where scalability is or will ever be a concern, so I wasn't looking at it from that perspective.

As for logout_actions, I just meant that it should ideally be defined within the components array settings if you integrate this code into the official plugin source code. Individual developers could still choose to store the values in their own config file setting, and simply set the component settings array from their config file values. But at least that way they would be able to choose between defining in the settings array directly or using the config file.

If your code isn't added to the official plugin source, then it doesn't really matter anyway.

pennycoders commented 11 years ago

@aldeed : Great suggestion aldeed, thanks!

jashim78 commented 8 years ago

Informatve