Facebook API SDK (PHP) clearing site sessions
I am successfully using the Facebook SDK (PHP) to connect users to my site, but I'm having issues when they authenticate their account. Their account is successfully authenticated, but for some reason my site's sessions are cleared.
Flow:
- User logs into my site (local username and password)
- User connects to Facebook in a popup
- Facebook authenticates user and returns back to my site
- My sites session is now invalid (both in the popup and main window) causing the user to be logged out
I am using the Facebook SDK (PHP) and my site uses the CakePHP framework
Any help will be greatly 开发者_运维百科appreciated.
I can't tell you what is deleting your session, but you might want to try this (works for me)
use the Javascript SDK to display the login buttons that will open the popup to connect to FB
add the js SDK to your page like this:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({appId: '<?php echo FB_API_ID; ?>', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.login', function() {
new Request({
'method': 'get',
'url': '<?php echo $this->Html->url(array('controller'=>'users','action'=>'login_fb'));?>',
'onSuccess': function(result){
window.location.reload();
}
}).send();
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
On the auth.login
event i'm using an ajax call to /users/login_fb that will use the Facebook SDK to check the facebook session:
App::import('Lib', 'facebook_sdk/facebook');
// "MyAuth" is a custom Auth Component that extends the normal Auth component
$this->MyAuth->facebook = new Facebook(array(
'appId' => FB_API_ID,
'secret' => FB_SECRET,
'cookie' => true,
));
$me = null;
$session = $this->MyAuth->facebook->getSession();
if ($session) {
try {
$uid = $this->MyAuth->facebook->getUser();
$me = $this->MyAuth->facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
}
}
if ($me) {
$this->Session->write('FbLogin.session',$session);
$this->Session->write('FbLogin.user',$me);
$UserModel = ClassRegistry::init('User');
$user = $UserModel->findByUid($me['id']);
if(!$user){
$UserModel->create();
$user_data = array( 'username'=>$me['username'],
'name'=>$me['first_name'],
'lastname'=>$me['last_name'],
'email'=>$me['email'],
'group_id'=>GROUP_VISITOR,
'uid'=>$me['id']
);
$UserModel->save($user_data);
$user['User']['id'] = $UserModel->id;
}
$this->Session->write($this->MyAuth->sessionKey, $user['User']);
$this->MyAuth->_loggedIn = true;
}
}
the main idea is that.. in js i call an ajax to check the fb session and then save it in the cake session , and the js will refresh the page
Could be worth checking the Cake security level, it might be doing referrer checks (I think it does this in the "high" setting, maybe the "medium" as well), which would be invalidating the session.
I couldn't find out why the session was being reset so decided not to use the SDK for the authentication. This is what I used instead.
$code = (isset ($_REQUEST['code']) ? $_REQUEST['code'] : null);
if (empty ($code)) {
$dialogUrl = 'http://www.facebook.com/dialog/oauth?client_id=' . $this->appId . '&redirect_uri=' . urlencode($this->url) . '&scope=' . implode(',', $this->scope);
header('Location: ' . $dialogUrl);
die;
}
else {
$tokenUrl = 'https://graph.facebook.com/oauth/access_token?client_id=' . $this->appId . '&redirect_uri=' . urlencode($this->url) . '&client_secret=' . $this->secret . '&code=' . $code;
$accessToken = file_get_contents($tokenUrl);
$this->Session->write('facebookAccessToken', $accessToken);
$graphUrl = 'https://graph.facebook.com/me?' . $accessToken;
$fbUser = json_decode(file_get_contents($graphUrl));
if ($fbUser) {
...
}
}
精彩评论