I'm trying to show the feed and events of a Facebook fanpage on a website. I'm using the php sdk to call the Facebook graph api. I also created an app on my Facebook account and have an app ID, app secret and app token.
I don't want to log in the user of the website. I just want to integrate the events and news data of the Facebook fanpage on the website.
My question is: Can I use the static app token to make graph api calls with php from my server and build my website after that, so that no one will receive the app token? Or is this bad because of security issues?
Here is the code:
$app_ID = '{appID}';
$app_secret = '{appSecret}';
$app_token = "{staticAppTokenFromFacebookDeveloperSettings}";
$facebook_page_ID = '{facebookPageID}';
$fb = new Facebook\Facebook([
'app_id' => $app_ID,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.7',
]);
$fb->setDefaultAccessToken($app_token);
try {
$response = $fb->get('/' . $facebook_page_ID . '/feed');
//$response = $fb->get('/' . $facebook_page_ID . '/events');
// ...
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
Thank you very much!
You have to put the App Secret somewhere in order to use an App Access Token, and the server is the only place where it is safe. Just keep in mind that there are limits to API calls, you should cache results in your own database. Do not call the feed and events endpoints for every single user hit.
Related
I try to have an app that can pause/resume my adset (accounts owned by myself).
I get no error message(or anything) output when requesting this
$adset = new AdSet($adsetid);
$adset->campaign_status = AdSet::STATUS_ACTIVE;
try{
$adset->updateSelf();
} catch (RequestException $e) {
$response = json_decode($e->getResponse()->getBody(), true);
var_dump($response);
}
But I see that the adset status did not change.
Now, I do see that the Marketing API, Settings section shows me that the API access Level is development and the app doesn't have Ads management standard access.
When I check permissions at App review > Permissions and features it shows 'Standard access' and 'ready to use'. (however not 'Active')
And at the same time my request count and error rate in the past 30 days are acceptable.
I don't understand what is missing to make it work. Can anyone help me out?
The code I have shown in my question was based on the code I copied from the Facebook marketing API documentation.
Strangely when I simulated my request using the Graph API Explorer and hit the "Get code" button it will suggest you a different code.
When I used that code instead of the code of the marketing API docs it did seem to work just as expected.
This code worked as opposed to the code from the docs:
$adsetid = "YOUR ADSET ID";
$access_token = "YOUR ACCESS TOKEN";
try {
$response = $fb->post(
'/'.$adsetid,
array (
'fields' => 'status',
'status' => 'ACTIVE'
),
$access_token
);
} catch(FacebookExceptionsFacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
$graphNode = $response->getGraphNode();
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
In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.
I have built an app using the PHP Facebook SDK. It allows users to authenticate my app with facebook OAth so that they can update their status' via my App. This works great, however a lot of my users have business pages and they want to update the status on their business page not their main personal feed. How is this possible? Below is what I have so far.
if ($status != ''){
try {
$parameters = array(
'message' => "$status"/*,
'picture' => $_POST['picture'],
'link' => $_POST['link'],
'name' => $_POST['name'],
'caption' => $_POST['caption'],
'description' => $_POST['description']*/
);
//add the access token to it
$parameters['access_token'] = $access_token;
//build and call our Graph API request
$newpost = $facebook->api(
'/me/feed',
'POST',
$parameters
);
$success['status'] = "$xml->status";
$xml2 = new XMLGenerator($success, 'facebook','status');
$returnData = $xml2->output;
$returnData = APIResponse::successResponse('200', "$xml->status");
} catch (Exception $e) {
$returnData = APIResponse::errorResponse('400', 'Facebook Error: '.$e);
}
I assume I would have to change '/me/feed'? but to what? What is they have multiple pages how would my app know which page to post to?
Any help with this would be much appreciated.
You can substitute me with the PAGE_ID to post to a page e.g., /013857894/feed. Make sure that you have completed the OAuth process with the manage_pages and publish_stream permissions. You can learn more at the link below:
https://developers.facebook.com/docs/reference/api/page/#statuses
If the user has multiple Pages then you will first need to give them some way of selecting which page they want to post to. You can find out which Facebook Pages a given user is the administrator of by calling /me/accounts for that user. You can find out more about this approach in the Connections section of this page:
https://developers.facebook.com/docs/reference/api/user/
When a user comes into my app via an apprequest, Facebook appends a request_id to the URL.
I am trying to access this object before the user authorizes my application. When I try to make the api call:
FB.api('/'+requestId, function(response){ console.log(response); });
it returns the following:
error: Object
message: "An access token is required to request this resource."
But I should have access since it was my app that sent the request in the first place!
I did some digging, and I noticed that on the PHP side, it will use the user_access_token if available, and the app_access_token otherwise.
Is this a security limitation (i.e: cannot expose the app_access_token on the client side) or am I doing something wrong?
Any insight would be helpful. Thanks!
when you make a request to /{user_id}/apprequests you have to have authorized the user already...
Since the request was created by your application - only your application can manage -ie delete or read requests that were sent. Essentially, before the user authorizes you app he/she is anonymous to your application - therefore it would not be possible to read that users requests because you "dont know" who they are...
Hope this helps...
The following blog posts describes how to interact with requests and should hopefully answer your questions.
http://developers.facebook.com/blog/post/464
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$token_url = "https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $app_id .
"&client_secret=" . $app_secret .
"&grant_type=client_credentials";
$access_token = file_get_contents($token_url);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$user_id = $data["user_id"];
//Get all app requests for user
$request_url ="https://graph.facebook.com/" .
$user_id . "/apprequests?" .
$access_token;
$requests = file_get_contents($request_url);
//Print all outstanding app requests
echo '<pre>';
print_r($requests);
echo '</pre>';
//Process and delete app requests
$data = json_decode($requests);
foreach($data->data as $item) {
$id = $item->id;
$delete_url = "https://graph.facebook.com/" .
$id . "?" . $access_token . "&method=delete";
$result = file_get_contents($delete_url);
echo("Requests deleted? " . $result);
}
?>
You have access to the app generated requests as the user follows the request via your app token but you need the user token to access the rest of the users requests.