Facebook PHP SDK - Have to reauthenticate during new browser session? - facebook

Hopefully this should be quick and easy.
session_start();
include("facebook.php");
$facebook = new Facebook(array(
'appId'=>'xxxxx50274xxxxx',
'secret'=>'xxxxxb932d62fbc6287feb18e5exxxxx',
'cookie'=>true
));
$fbuser = $facebook->getUser();
if (empty($fbuser)){
$fbloginurl=$facebook->getLoginURL();
echo "<html><body><a href='$fbloginurl'>Click</a></body></html>
} else {
die("Authenticated");
}
In this example, the first time I click the link to give permissions to the app to access my FB account, everything works fine. I can keep refreshing the page, and I get the "Authenticated" confirmation.
However, every time I restart the browser (starting a new session), it doesn't authenticate the app automatically and I have to click the link again. Of course as soon as I click the link I am immediately redirected back to the source page and presented with the "Authenticated" confirmation.
Is there any way of not having to click the authentication link during new browser sessions and have it authenticate automatically? I need to do this without a PHP Header directive, as I want the first time the user gives permissions to the app to be triggered by a manual click.
My FB login is persistent ("stay logged in" option is checked).
Thanks a lot for any help.

If I am understanding your scenario correctly (this is not an iframe app, correct?), this is all down to losing the website session cookie when the browser is closed. Once that cookie is gone, there is nothing to identify the user to your server-side code and so no way to know if the user has previously authorized your app.
You need to find a way to persistently identify the user, or at least identify that he has already given permissions. The simplest way would probably be to set your own (permanent) cookie once the user has first authenticated. Then whenever the session cookie is lost, check the presence of the permanent cookie and if it's there, do a PHP redirect to Facebook (which will be invisible to the user). If there is no cookie, present the HTML link to the user like you are doing now.

Comparing it to my code, the only difference I see is that I check to see if $fbuser is valid - if it isn't send me to the login screen. I'm also using top.location.href.
// Login or logout url will be needed depending on current user state.
if ($fbuser) {
$logoutUrl = $facebook->getLogoutUrl();
}
else {
$loginUrl = $facebook->getLoginUrl(array('scope' => 'publish_actions', 'canvas' => 1, 'fbconnect' => 0, 'redirect_uri'=>config_item('facebook_url').$pf));
echo "<html><body><script> top.location.href='" . $loginUrl . "'</script></body></html>";
exit(0);
}
Hope that helps.

Related

Facebook PHP SDK usage stand alone - how do the Facebook sessions/cookies work?

I'm utilizing the Facebook PHP SDK on its own. I do not want to use the JS SDK at all.
Because getUser(); from the SDK can return a user id even if the user is not logged in, I have opted for using a try/catch statement to check if the user is logged in.
try
{
$me = $CI->facebook->api('/me');
$CI->our_fb['is_fb']='YES';
echo "hello";
}
catch(FacebookApiException $e)
{
echo "catch";
}
This statement is included in the global include file of all of my files (for simplicity).
So, depending on the situation, I generate a Facebook login URL. The expected functionality is that the user logins to Facebook, authorises the app, is returned to the redirect URI set in the login URL at which point the try statement will execute, and $CI->our_fb['is_fb'] will be set.
This is however not happening.
If the user is already logged into Facebook and the app is authorised, it works perfectly. SUCCESS
If the user is not logged into Facebook, once redirected the variable is not set. FAILURE
If the user is logged in but the app is NOT authorised after redirect the variable is not set. FAILURE.
In the latter two cases if you simply refresh the page, the variable is set - SUCCESS. Refreshing the page is however unnecessary/pointless extra effort.
My problem is that if you need to login to FB/or authorise the app e.g the first time you login with FB, you have an additional unneeded refresh, and I don't know why.
I suspect it is something to do with the cookie/session? Which saves the access token that I assume is returned/passed to the SDK automatically not being set at the same time?
Anyone got any ideas?
If you're having an app on facebook (tab or canvas). PHP SDK only get the User ID on initial loading of a page because a signed_request is sent with the request to your app.
But, when the app refreshes, the signed_request is lost (as it's facebook who send it).
So, in this case, you can append the signed_request to every URLs your use in your app - but that's really not optimal as the signed_request won't be regenarated - neither refreshed.
Your only real option is to rely on the JS SDK to set cookie correctly and allow getUser to work as expected. This is required because you're considered as a third-party app in Facebook (being in an iframe) and most browser will block you from setting cookies - so you need a work around handled by the JS SDK for you. You can search for cross-domain cookies or third-party cookie for explanation about the workarounds, but these workaround only work via JS scripting and iframe management.
Also, be sure to setup the JS SDK correctly: channel file, cookie allowed, and send P3P headers (for IE).
You can also check this related question: A proper approach to FB auth
About website, the same mostly stays (but you have no signed_request). At this point, seriously consider using the JS SDK as it's way easier. Or else, you can make sure your app flow follow these guidelines: https://developers.facebook.com/docs/concepts/login/login-architecture/
The way I am seeing this is, you are trying to avoid that refresh if the user is not logged in and precedes to log in after the page has initially loaded.
So what you can do is make an ajax request to another page on your site, say for example id.php, which just loads the php sdk and echo $userid; and then you can grab the user id after login without the refresh.
Basically the cookie is used to save the signed request and session is used to save 'state', 'code', 'access_token', 'user_id'. If the above are present PHP SDK uses them, no matter if they are valid or not.
I think your problem lies in the CODE sent by facebook. Specifically these lines in base_facebook.php:
if ($code && $code != $this->getPersistentData('code')) {
$access_token = $this->getAccessTokenFromCode($code);
...
protected function getAccessTokenFromCode($code, $redirect_uri = null) {
if (empty($code)) {
return false;
}
if ($redirect_uri === null) {
$redirect_uri = $this->getCurrentUrl();
}
...
Because CODE is issued for specific url sometimes there is such situation: Visitor arrives on www.example.com. He givies permissions and is redirected to example.com/login. But the code is not valid there, so the getUserAccessToken returns false. When you refresh the page you get same urls and everything's fine.
You're on the right track of not using getUser() because as I wrote above it's taken from the session if available.

Redirect to facebook app after login from auth dialog

I got some problem with my testing app
$params = array(
'scope' => 'read_stream, publish_stream'
);
$loginUrl = $facebook->getLoginUrl($params);
echo "<script type='text/javascript'>top.location.href = '$loginUrl';</script>";
This is the code I use to send user who has not logged in yet to login
via facebook auth dialog.
The problem is after login using facebook auth dialog
user will be redirected to my site which is not in facebook app.
How can I send user back to facebook app after login using auth dialog ?
Please help
You can use the redirect_uri parameter of getLoginUrl() to tell facebook where you want to send the user after authorization ends (let it be success or failure).
There's a number of restrictions on what you can use there, basically you got three options:
URL under your application's domain.
The canvas path of the application (if it has one): https://apps.facebook.com/YOUR_APP_NAMESPACE
Any page url that has your application installed: https://www.facebook.com/PAGE_USERNAME/app_YOUR_APP_ID
By default, the php sdk takes the current url as redirect_uri. The documentation about these are under the oauth dialog's documentation of the same parameter.
Was google-ing about the same issue and found a solution,so thought might as well answer her.
simply add the following code in the main page.
$config['appBaseUrl'] = "http://apps.facebook.com/your_app_name/";
if(isset($_GET['code']))
{
header("location:" . $config['appBaseUrl']);
exit;
}
$config is the array that i pass while creating the facebook object. In this context,its not necessary to create an array though.

facebook getLogoutUrl

facebook, as usual does not work as expected.
on calling
$facebook->getLogoutUrl($params);
using
$params = array( 'next' => 'http://mywebsiteurl.com/loggedout.php' );
The browser view is redirected to loggedout.php, which is good.
Except when the user proceeds to facebook.com they find they are still logged in, which is not good.
So, where do we go from here?
What am i doing wrong?
What did facebook do wrong?
it's because of the cookie. I did the following to fix this issue ...
in the params for the getLogoutUrl method you set your own logout URL:
$facebook->getLogoutUrl(array( 'next' => 'http://www.yourdomain.com/logOut/' ));
and in your logout file you reset the cookie:
setcookie('PHPSESSID', '', time()-3600, '/');
header('Location: http://www.yourdomain.com');
I have the same issue. After returning from the logout URL, calling $facebook->getUser() still returns the user's id.
I got around this by adding a query string to the 'next' parameter, which if set, I treat the user as if they were logged out.
I've had similar issues with the SDK, where using the getLogoutUrl(); with a next parameter does not ever get redirected back to the web-application.
So, I've given up on getting the users to be able to use that functionality to dis-connect my application. Now I just delete their access tokens from our system and tell them to manually de-authorise the application on the FB site - and provide a hyperlink to http://www.facebook.com/settings?tab=applications

Directing users to facebook login page without asking for permissions

I'm trying to redirect users to the facebook login page then back to my app without the Log In to app page displaying. Is this possible?
I've looked into the "next" parameter which is automatically generated by the PHP-SDK but cannot seem to change it.
Is there anyway to do what I'm looking for? I want to make sure users are logged in in order to check to see if they have authed my app but do not want them to if they are not already.
Thanks for any help!
No, i don't think it is possible to modify the next parameter. The only place where i saw the next parameter(in the PHP SDK) is in the getLogoutUrl() function, as seen in the source of the base_facebook.php. And that parameter defines which url to go, after logout.
For getLoginUrl() in the base_facebook.php file, we have
return $this->getUrl(
'www',
'dialog/oauth',
array_merge(array(
'client_id' => $this->getAppId(),
'redirect_uri' => $currentUrl, // possibly overwritten
'state' => $this->state),
$params));
as the last line in the function, which obviously means that the oauth-dialog will be shown, no matter what you try.
If your app is not on Facebook, then you can go for <fb:login-button>Login with Facebook</fb:login-button> in Javascript, and subsequently follow the example from this url. You'll see there that it's not possible to remove that dialog entirely, even if you don't ask for any permissions.
The Javascript SDK's FB.login() method will also bring up the auth dialog.
Hope this helps.
They have to accept permissions for the first time only. Facebook will never let you to get user's data without their knowledge/accept
If you are using php :
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
'cookie' => true
));
//Facebook Authentication part
$user = $facebook->getUser();
if (!$user) {
// user is not logged on --> redirect to the login url
} else {
// user is logged on you can do what you want
}

Facebook authentication with codeigniter (active access token must...)

I sign in with FB fine if I directly create a page at domain.com/someurl.php
The moment I copy the same code (inc html) into a view file with codeigniter and go to domain.com/login/someurl.html it doesn't work. By it doesn't work I mean, I get an exception if i try to access /me after signing into facebook.
The message reads "An active access token must be used to query information about the current user"...
In my controller i have my index function and all it does is load the view with the facebook login code.
I thought I may be doing something wrong but I copied the sample.php from the facebook sdk and paste it into the view file and the same thing happens. If i copy the sample code into the file at someurl.php it then works as expected...given the situation I suspected it may be something to do with codeigniter and possibly some config option I have that causes that behaviour...
I've been looking up the error for a while now and have found a few resources:
http://benbiddington.wordpress.com/2010/04/23/facebook-graph-api-getting-access-tokens/
Facebook access_token invalid?
Facebook authentication issue
https://github.com/facebook/php-sdk/wiki/AccessToken
but none of the suggested fixes have worked.
Right from the sample:
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => 'APPID',
'secret' => 'SHHHH',
));
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
// Login or logout url will be needed depending on current user state.
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$loginUrl = $facebook->getLoginUrl();
}
It doesn't work in the view and I'm stumped as to why or why none of the fixes or "precautions" such as not using type or ensuring the redirect url is the same etc, work.
EDIT:
I'm trying to avoid using domain.com/somefile.php and instead use a view file like every other page...
The issue has cropped up in other places such as the Elliot Houghin fb/CI library.
I found a solution documented in a tutorial here:
http://www.dannyherran.com/2011/02/facebook-php-sdk-and-codeigniter-for-basic-user-authentication/
The problem could be cause from one of several issues pointed out on a an issue on Elliot's github repo. I tried many of the suggested "fixes" but the one that seemed to help was not using the facebook instance as a class property. After trying the tutorial at the above link I tried a fresh install of CI again and created a facebook instance inside the function, the API calls with the FB SDK then worked and had no problems so far.
Bug report with suggested fixes #
https://github.com/elliothaughin/codeigniter-facebook/issues/5