I am trying to find a way to keep connected with the Facebook API once authorised using OAuth but am having problems. I dont want the users of my App to have to login via Facebook every time they want to use my app.
I store the oauth access toekn in a database after the user authenticates with facebook and I have "offline_access" permissions set, so in theory, this should be possible.
However, I get "Uncaught OAuthException: An active access token must be used to query information about the current user." when trying to connect to Facebook API using a saved Oauth token stored in a database.
header("p3p: CP=\"ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV\""); // hack to stop facebook wierd cookie problems
//instantiate the Facebook library with the APP ID and APP SECRET
$facebook = new Facebook(array(
'appId' => 'appid',
'secret' => 'secretid',
'cookie' => true
));
//Get the FB UID of the currently logged in user
$user = $facebook->getUser();
//if the user has already allowed the application, you'll be able to get his/her FB UID
if($user) {
//get the user's access token
$access_token = $facebook->getAccessToken();
} else {
//see if authorisation already set up in DB
$query = mysql_query("SELECT oauth_token FROM PingSocialMediaUsers WHERE oauth_provider = 'facebook' AND clientID = '$clientID'");
$result = mysql_fetch_row($query);
$access_token = $result[0];
}
if($access_token) {
//check permissions list
$permissions_list = $facebook->api(
'/me/permissions',
'GET',
array(
'access_token' => $access_token
)
);
//check if the permissions we need have been allowed by the user
//if not then redirect them again to facebook's permissions page
$permissions_needed = array('publish_stream', 'read_stream', 'offline_access');
foreach($permissions_needed as $perm) {
if( !isset($permissions_list['data'][0][$perm]) || $permissions_list['data'][0][$perm] != 1 ) {
$login_url_params = array(
'scope' => 'publish_stream,read_stream,offline_access',
'fbconnect' => 1,
'display' => "page",
'next' => 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']
);
$login_url = $facebook->getLoginUrl($login_url_params);
header("Location: {$login_url}");
exit();
}
}
//if the user has allowed all the permissions we need,
//get the information about the pages that he or she managers
$accounts = $facebook->api(
'/me',
'GET',
array(
'access_token' => $access_token
)
);
//add to details database
//find the user by ID
if ($user != ''){
$query = mysql_query("SELECT * FROM PingSocialMediaUsers WHERE oauth_provider = 'facebook' AND oauth_uid = '$user'");
$result = mysql_fetch_array($query);
// If does not exist add to database
if(empty($result)){
$query = mysql_query("INSERT INTO PingSocialMediaUsers (oauth_provider, clientID, oauth_uid, username, oauth_token, oauth_secret) VALUES ('facebook', $clientID, $user, '{$accounts['name']}', '$access_token', '')");
$query = mysql_query("SELECT * FROM PingSocialMediaUsers WHERE id = " . mysql_insert_id());
$result = mysql_fetch_array($query);
} else {
//update the tokens
$query = mysql_query("UPDATE PingSocialMediaUsers SET oauth_token = '$access_token', oauth_secret = '' WHERE oauth_provider = 'facebook' AND oauth_uid = '$user'");
}
//save the information inside the session
$_SESSION['_token'] = $access_token;
$_SESSION['accounts'] = $accounts['data'];
}
$facebookAuth = TRUE;
Facebook pass an expires field when it pass your application the access token and default as per the Facebook is 2hours.
there are other factors why which a access_token can expire and here are the complete details for you
Ankur Pansari
How-To: Handle expired access tokens
Now next we can talk about offline_access which means
It Enables your app to perform authorized requests
on behalf of the user at any time. By default,
most access tokens expire after a short time period to ensure applications
only make requests on behalf of the user when the are actively
using the application. This permission makes the
access token returned by our OAuth endpoint long-lived.
So it all means you have to make sure you always using valid access_token.For details about various permission here is a reference link
Facebook Permissions
Related
I'm using Laravel 5.4 and Socialite to allow the visitor of my site to log in.
Situation
I recently obtained the user_events permission cause I wanted to add some functionalities to my website.
Before this, some users got registered in my database along with their user token in the database. (token than includes the default permissions but not user_events)
I updated the SocialAuthController.php to reflect the new permission on the new created user and this is working great
return Socialite::driver('facebook')
->scopes(['public_profile', 'user_events'])
->redirect();
Problem
If a user is already registered in the database with his token, it is impossible to run this command $fb->get('me/events') since the token does not include the user_events permissions.
Questions
Is there a way to force a user to grab a new token with a new permission without having to remove him from the database ? ( I have data associated with users) ?
SocialAuthController
public function handleProviderCallback(SocialAccountService $service)
{
$user = $service->createOrGetUser(Socialite::driver('facebook')->user());
}
SocialeAccountService
public function createOrGetUser(ProviderUser $providerUser)
{
$account = SocialAccount::whereProvider('facebook')
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => 'facebook',
'nickname' => $providerUser->getNickname(),
'avatar' => $providerUser->avatar_original,
'token' => $providerUser->token,
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
I'm using "facebook/php-sdk-v4": "dev-master".
Here is my code.
$this->helper = new Facebook\Helpers\FacebookRedirectLoginHelper('http://localhost:8000/test2');
$this->helper->getLoginUrl(['scope'=>'user_about_me,user_groups'])
//test2 controller
session_start();
$session = $this->facebook->getSessionFromRedirect();
$request = new Facebook\FacebookRequest($session, 'GET', '/me/groups/');
$response = $request->execute();
$graphObject = $response->getGraphObject();
Here is the login link:
https://www.facebook.com/v2.0/dialog/oauth?client_id=335104339978143&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Ftest2&state=0d09d4965509ccb3dc78f2fffc44c11e&sdk=php-sdk-4.1.0-wip&scope=user_about_me%2C+user_groups
When I use the fb account that I registered the app, I can get the groups and the permission on login popups. But when I use other facebook accounts, the permission does not popup and I get no result.
You are asking for additional permissions in the incorrect way. You need to do the following using Facebook PHP SDK v4.0.9:
// generate login url with scope, each permission as element in array
$loginUrl = $helper->getLoginUrl( array( 'email', 'user_friends' ) );
// output login link
echo 'Login';
Source
What I am actually trying to do is to retrieve my posts/statuses from my personal facebook profile page (this is not a fan page) and display them in my website. Also please note that every user that will visit my website should be able to view my statuses by means it does not have to do with authenticating them or something like that. This is something that needs to be generated server-side.
I am aware that you can retrieve a JSON string from a URL like this https://graph.facebook.com/MY_PROFILE_ID/feed?access_token=ACCESS_TOKEN because I tried it from the facebook developers (Graph API Explorer) page and it is exactly what I need.
The thing is that when I generate the access token from the Graph API Explorer I can select permissions and it generates the token respectively according to permissions chosen, such as user_status, status_update, etc.
Now I want to accomplish this by using PHP-SDK but I have no idea how to generate an access token the same as the one I generate in the Graph API Explorer.
The basic way to do this is by calling getAccessToken() as shown here. The thing is that when I use the token generated from this simple method the JSON string returned will only show me my basic information.
$config = array(
'appId' => 'MY_APP_ID',
'secret' => 'MY_APP_SECRET',
);
$facebook = new Facebook($config);
$ACCESS_TOKEN = $facebook->getAccessToken();
How can I add permissions for instance? Should I assign parameters somewhere? I spent quite a lot of time reading the facebook API documentation and some other forums but I did not find the answer that I need.
Finally if I get the right access token than I would simply retrieve the JSON string and parse it with what I need.
Thanks.
you need for add permissions in your code for login using the fb js sdk add in the scope this like this example:
$("#login").on('click',function(){
FB.login(function(response){
console.log(response);
},{scope: 'email,manage_pages,read_insights'});
});
or in php fb sdk the next form:
<?php
require 'server/fb-php-sdk/facebook.php';
$app_id = 'APP_ID';
$app_secret = 'APP_SECRET';
$app_namespace = 'APP_NAMESPACE';
$app_url = 'https://apps.facebook.com/' . $app_namespace . '/';
$scope = 'email,publish_actions';
// Init the Facebook SDK
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
));
// Get the current user
$user = $facebook->getUser();
// If the user has not installed the app, redirect them to the Login Dialog
if (!$user) {
$loginUrl = $facebook->getLoginUrl(array(
'scope' => $scope,
'redirect_uri' => $app_url,
));
print('<script> top.location.href=\'' . $loginUrl . '\'</script>');
}
?>
the most important for add permission is this part :
$scope = 'email,publish_actions';
you can find all about the extended permissions in this link
https://developers.facebook.com/docs/reference/login/extended-permissions
Is there any way I can get access token of any page by page id, I should be able to post on page behalf of admin?
I'm guessing you don't want to be admin of your clients' pages:
You could create a page so that your clients login to Facebook and
grant permissions to your app.
Then you can get the page access token and save it in your DB.
Finally use that access token to post directly to each page as
admin without being you the actual admin.
Quoting Facebook documentation:
To obtain a page access token you need to start by obtaining a user
access token and asking for the manage_pages permission. Once you have
the user access token you then get the page access token via the Graph
API.
To get user access token (supposing you are logged in to fbk and have granted permissions to your App):
$user = $facebook->getUser();
if(!$user) {
$login_url_params = array(
'scope' => 'publish_stream,read_stream,manage_pages',
'fbconnect' => 1,
'redirect_uri' => 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']
);
$login_url = $facebook->getLoginUrl($login_url_params);
//redirect to the login URL on facebook
header("Location: {$login_url}");
}
Don't forget get to a time extended access token
$facebook->setExtendedAccessToken();
$access_token = $facebook->getAccessToken();
With that token you can get the page token via the API:
$accounts = $facebook->api(
'/me/accounts',
'GET',
array(
'access_token' => $access_token
)
);
$accounts will be an associative array with all the info of the pages you admin (including the tokens for each page). To get the token of an specific page knowing its ID:
$accounts = $accounts['data'];
foreach($accounts as $account){
if( $account['id'] == $pagId ){
//$pagId would be the ID of the page you want to use
//This is the token of the page with the ID $pagId
$page_access_token = $account['access_token'],
}
}
I'm trying to retrieve users events using the facebook php sdk, but i'm stuck, the api return an empty array
$user = $me['id'];
$fql = "SELECT eid, name, start_time, end_time
FROM event
WHERE eid IN (SELECT eid
FROM event_member
WHERE uid = 1552544515)
ORDER BY start_time LIMIT 5";
$params = array(
'method' => 'fql.query',
'query' => $fql,
);
try {
$result = $facebook->api($params);
} catch (FacebookApiException $e) {
echo $e->getMessage();
}
thanks in advance.
If this is returning nothing, the most likely reason is that your user hasn't granted the user_events Permission during the Authentication flow.
Looking at your comments above, you may have added user_events to the permissions granted when a user goes through the Authenticated Referrals flow or via App Center, but regular users accessing the app directly need to go through one of the authentication flows from the document above, you're probably not doing this