FacebookI am using facebook javascript sdk to loigin a user, and then I wish to get some of his info via the php sdk, but I keep getting "An active access token must be used to query information about the current user."
this is the relevant html/js code:
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : '8', // App ID from the app dashboard
channelUrl : '//url/frontend/channel.php', // Channel file for x-domain comms
status : true, // Check Facebook Login status
cookie : true,
oauth:true,
xfbml : true // Look for social plugins on the page
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
if (response.status === 'connected') {
submitform();
} });
};
function submitform() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me?fields=email,name', function(response) {
//submits a form from this page...
});
}
</script>
Facebook
and the php that fails is :
$facebook = new Facebook(array(
'appId' => Configuration::$facebook_app_id,
'secret' => Configuration::$facebook_app_secret));
// Get User ID
$user_profile = $facebook->api('/me?fields=name,id','GET');
It seemed to work for a while, and then it breaks with
" [message] => An active access token must be used to query information about the current user.
[type] => OAuthException
[code] => 2500",
Anyone has an idea how to stabilize this?
Thanks
Maybe that happens because your acces token was expired?
There are several access token types. And if your access token is a "short-term token" - you must refresh it.
you can read abot acces tokens here https://developers.facebook.com/docs/facebook-login/access-tokens/
In python server lib for facebook i used method fetchToken(appId, secret) to refresh my expired token.
Related
I was implementing FB social login in website based on PHP. I checked FB website and found it easy to implement. Below is the approach i have followed and i am not sure that i have any security issues here.
I have used Facebook JS SDK approach.
and is as follows:
var appID = 'xxxxxxxxxxxxxxx';
window.fbAsyncInit = function() {
FB.init({
appId : appID, // App ID
channelUrl : '',
status : true,
cookie : true,
xfbml : true,
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// connected
FB.api('/me?fields=id,name,email,permissions', function(response) {
//alert('Good to see you, ' + response.name + '.');
});
}else{
}
});
};
function login() {
if( navigator.userAgent.match('CriOS') ){
}
else{
FB.login(function(response) {
if (response.authResponse) {
replace_login();
} else {
// cancelled
alert('User cancelled login or did not fully authorize.');
}
},{scope: 'email,public_profile,user_friends'});
}
}
function replace_login(){
FB.api('/me?fields=id,name,email', function(response) {
$.ajax({
url: "s-account",
type: 'POST',
data: response,
dataType: 'json',
beforeSend: function(){
$("#signin_fb").button('loading');
},
success: function(data) {
$("#signin_fb").button('reset');
window.location.reload();
},
error: function(){
$("#signin_fb").button('reset');
}
});
});
}
And in PHP at server side, i am storing user detail like social_id, name and email in database through ajax call and if DB operation is successful then i am setting Session Variable in my website with username and email and user is logged in successfully.
For logout, i am using my own logout function to destroy Website user session and user is successfully logged out.
Now, where is the security risk? because if user is logged out and then try to login again JS SDK shall get a new Access Token through new response.
This whole authentication process boils down to the ajax call to s-account. You're sending name and email from FB.api() to your back end application in a POST request and as you didn't mention, I presume you're not verifying the access token with these details on the server side and you're simply making a session based on these details.
The security issue
Now, the security issue is that you're using a client side authentication on the server side. A user can simply generate a POST request to s-account with a fake response like Facebook with any username and email address and your PHP application will authenticate the user and make a valid session without verifying if the details are coming from a legit source. Your authentication is completely broken at this stage because a malicious user can login with any account by generating a simple POST request to s-account with any email and username.
How to fix
Facebook provides an end-point in the graph API which validates an access token and returns the details of the user associated with this access token. From the Docs:
This endpoint returns metadata about a given access token. This
includes data such as the user for which the token was issued, whether
the token is still valid, when it expires, and what permissions the
app has for the given user.
The Fb.Login() will generate the access token as response.authResponse.accessToken and userId as response.authResponse.userID. You need to send this accessToken & userID along with the other user details in your ajax call to s-account and then use the following API end-point to validate if the details are legit.
curl -X GET "https://graph.facebook.com/v2.6/debug_token?input_token=USER_ACCESS_TOKEN_FROM_AJAX_CALL&access_token=YOUR_APP_ACCESS_TOKEN"
If the the access token is valid, you'll get the following response with the userID for which this token was issued.
{
"data": {
"app_id": "YOUR_APP_ID",
"application": "YOUR_APP_NAME",
"expires_at": 1462777200,
"is_valid": true,
"scopes": [
"email",
"manage_pages",
"pages_messaging",
"pages_messaging_phone_number",
"public_profile"
],
"user_id": "THE_USER_ID_ASSOCIATED_WITH_THE_TOKEN"
}
}
Now you can compare this userID with the userID you received in the ajax call and check if the details are legit.
How to get your APP_ACCESS_TOKEN
To debug the user access token using the debug_token API, you need to generate your APP access token on the server side using the following API end-point.
curl -X GET "https://graph.facebook.com/v2.6/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials"
This will return your app access token in response.
{
"access_token": "YOUR_APP_ACCESS_TOKEN_HERE",
"token_type": "bearer"
}
I'm trying without success for 2 days now to retrieve page feed with Facebook PHP SDK. Details :
I got a user, who is page admin
I created an app (not public, is that a problem?)
I use an AJAX called PHP script to try to retrieve feed, because I don't want to pollute main page loading.
All stuff given on PHP SDK doc is related to manual login and access token retrieval.
I Managed to retrieve a user token using the 2-scripts code (login, and callback), with manage_pages speical grant require :
$fb = new Facebook\Facebook([
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.2',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['manage_pages']; // Optional permissions
$loginUrl = $helper->getLoginUrl('http://domain.com/fb_callback.php', $permissions);
How can achieve the same thing without manual redirection, is one script, in AJAX context? SHould I use Curl to emulate manual redirection?
THing which puzzle me out is that the same stuff tok 2 lines using JS framework :
window.fbAsyncInit = function() {
// Framework init with Vinexpo app ID
FB.init({
appId : '012345789',
xfbml : true,
version : 'v2.4'
});
// Check status
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// If connected, get last 2 posts on Facebook page
FB.api(
"/page_ID/posts?limit=2",
{
access_token : response.authResponse.accessToken
},
function (responsePost) {
if (responsePost && !responsePost.error) {
// Fill tiles on social network panel
}
}
);
}
});
Thanks in advance for answers or leads.
If you just want to read the newsfeed of one of you pages via AJAX, you don't necessarily need the PHP SDK if you generate yourself an eternal page access token and use this for your plain HTTP requests.
Have a look at my answer here on how to get such a token:
Post to a facebook page without "manage_pages" permission using php
i want to authenticate my facebook profile with my website so i can pull infor from the page.
i was suggested to one time authenticate with the facebook api through a temp page. somewhat like:
<fb:login-button params="some permission" />
i am new to coding facebook apps. but this seems like fbml. how can i use it to authenticate my website with my own profile. i dont need users to log into my website. i just need to pull info from my page.
the facebook documentation is sparse and fragmented. all i got for the Login was this code fragment. I dont understand how i can authenticate a weblink through this method.
FB.login(function(response) {
if (response.session) {
// user successfully logged in
} else {
// user cancelled login
}
});
can anyone throw some light??
Let's start from the beggining:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml" xml:lang="en" lang="en">
It's required for fbml to work. Next:
<fb:login-button autologoutlink="true"></fb:login-button>
<div id="fb-root"></div>
These two lines create the "facebook login button", you should place them in your html where you want the button to appear.
Right before your closing body tag add:
<script type="text/javascript" src="https://connect.facebook.net/en_US/all.js"></script>
<script>
window.fbAsyncInit = function() {
FB.init({appId: 'YOUR APP ID HERE', status: true, cookie: true, xfbml: true});
FB.Event.subscribe("auth.login", function(response) {
if(response.session) {
// this is where you handle facebook's response
}
});
};
</script>
What you are doing here is first initializing the connection to facebook, with your app id (you need to create an application), and register an "auth.login" event. The auth.login event is triggered every time you click the facebook login button and successfully login to facebook, or facebook auto logins you based on their cookie.
You can find an explanation of the auth.login and other events here, look at the sidebar at the left, all events are listed.
The response is JSON formatted and it contains your basic session information:
{
status: 'connected',
session: {
access_token: '...',
expires:'...',
secret:'...',
session_key:'...',
sig:'...',
uid:'...'
}
}
You can read more about it here. If your status is indeed "connected" the next most important bit of information is the uid, this is your unique facebook identifier, a public id with which you can send further requests to facebook. What you do with the response is up to you. An obvious choice would be to send it via ajax to a script that logs you in your application.
To get more info from facebook you need to download the php sdk. To use the sdk:
<?php
include_once "facebook-sdk-3.0.0/src/facebook.php";
$appID = "YOUR APP ID";
$appSecret = "YOUR APP SECRET";
$cookie = "fbs_{$appID}";
$cookie = isset($_COOKIE[$cookie]) ? trim($_COOKIE[$cookie], '"') : "";
if(empty($cookie)) {
echo "no facebook cookie";
die();
}
parse_str($cookie, $data);
$facebook = new Facebook(array(
"appId" => $appID,
"secret" => $appSecret,
"cookie" => true
));
$facebook->setAccessToken($data["access_token"]);
$user = $facebook->getUser();
$profile = $facebook->api("/me");
?>
So at first you parse facebook's cookie which is named "fbs_YOUR_APP_ID" and contains your session information (url encoded). What you actually need is the access_token (a unique identifier of the authenticated session), which was also returned to you in the JSON response object before. Then via the Facebook object you can do and api requests you want.
Now to have a full authentication mechanism you should create a similar connect script that instead of getting the session information from the cookie it should take them from the response object that is returned when auth.login occurs (possibly via ajax).
You should read the Authentication workflow document to better understand how facebook connect works.
A good and easy way to deal with Facebook authentication is to implement the server side flow with the Facebook PHP SDK (see on github). So you will have something like :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
If the user is logged in, then $user is his Facebook ID. You then have to check if you have a valid access token by making an API call :
If it does not raise any exception, then you have a valid access token
If it does, then you have to re-authenticate the user.
Here :
if ($user) {
try {
$facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
You need then to display the login or logout link :
<?php if ($user): ?>
Logout of Facebook
<?php else: ?>
Login with Facebook
<?php endif ?>
When the user is logged in and you have a valid access token, you can make API calls to get data from Facebook :
$user_profile = $facebook->api('/me');
You may want to check the example page of the Facebook PHP SDK which is well documented.
Hope that helps.
Is it possible for me to post a message on a given users facebook wall, if they perform a certain action on my website?
Basically, I am looking for a step by step guide to achieve this, as I have not been able to figure out how to do this via the facebook documentation.
Step 1:
Set up a new application at facebook. Enter details like your website address and domain name. Note down the api key, application id, and application secret. You can set up a new facebook application here. Note: To be able to access facebook developers dashboard you need to be a verified developer, i.e. you should either have your mobile number or credit card verified with it.
Step 2:
Set up an authentication method to check if user is logged into facebook and if facebook session exists ask for basic permissions from user. You can do this easily using PHP SDK:
$fb_sdk_path = FACEBOOK_SDK_PATH;
require_once($fb_sdk_path);
//initialize FB object
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_APP_SECRET,
'cookie' => true,
'domain' => 'example.com'
));
//try to get session. if this fails then it means user is not logged into facebook
$session = $facebook->getSession();
if (!$session) {
//get facebook login url
$url = $facebook->getLoginUrl(array(
'canvas' => 1,
'fbconnect' => 0
)
);
//put login url script to redirect to facebook login page (if you want to do this)
echo "<script type='text/javascript'>top.location.href = '$url';</script>";
exit;
} else {
//try to get user details from session this will trigger the permissions dialog.
try {
$uid = $facebook->getUser();
} catch (FacebookApiException $e) {
}
}
Step 3:
Use Facebook Javascript FB.ui method to generate a post form.
<div id="fb-root"></div> <!-- don't forget to include this -->
<script src="http://connect.facebook.net/en_US/all.js"></script><!-- include fb js -->
<script type="text/javascript">
//initialize facebook
FB.init({
appId:'YOUR_APP_ID',
cookie:true,
status:true,
xfbml:true
});
//call this function on click or some other event
function post_to_profile() {
FB.ui({
method: 'feed',
name: 'title of the feed',
link: 'link on the title',
caption: 'caption to show below link, probably your domain name',
description: 'description',
picture:'picture to show',
message: 'default message. this can be edited by the user before posting'
});
}
</script>
This should be enough to get it working.
I would recommend using the Javascript API. While you can certainly do it PHP, I find all the redirects required a poor user experience. Here is how you can get started loading the javascript API. It also has an example on how to post to a wall.
http://developers.facebook.com/docs/reference/javascript/
Posting to someones wall (yours or a friends) via javascript uses the FB.ui call.
http://developers.facebook.com/docs/reference/javascript/FB.ui/
Taken directly from http://developers.facebook.com/docs/guides/web/
<html>
<head>
<title>My Great Website</title>
</head>
<body>
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js">
</script>
<script>
FB.init({
appId:'YOUR_APP_ID', cookie:true,
status:true, xfbml:true
});
FB.ui({ method: 'feed',
message: 'Facebook for Websites is super-cool'});
</script>
</body>
</html>
This will open a prompt to post onto the currently logged in user's wall.
The getting started guide to the Graph API should help you. Specifically, you'll be dealing with the post object (that page contains a note about publishing, scroll down to the "Publishing" section). You'll also need the publish_stream permission, which you can learn more about here. And since you're doing this in PHP, the official Facebook PHP SDK will be of interest to you as well.
Here's the general flow
Register an app at developers.facebook.com
Create page w/ this link to this page: https://www.facebook.com/dialog/oauth?
client_id=164837516907837&
type=user_agent&
scope=email,read_stream,user_videos,friends_videos,user_about_me,offline_access&
redirect_uri=http://www.facebook.com/connect/login_success.html
Save the user x's oath token that is returned from step2
Via API call post to user x's wall
To reference: http://thinkdiff.net/facebook/graph-api-iframe-base-facebook-application-development/
Various steps involved
1)Register App at facebook
developers
2)Get PHP SDK of Facebook
3)Get Offline access from user
so that you can post in users wall
without his permission(Use
accordingly)
4)Save the access token given by
facebook for the user
5)Using the access token by php
SDK post into the wall
Check this question it may be of some help
Publishing To User's Wall Without Being Online/Logged-in - Facebook Sharing Using Graph API
I am using the following 2 API's to create a facebook connect but having issues with the sessions being picked up the the PHP SDK. I have downloaded the latest facebook-connect-js & facebook-php-sdk
Here is my initial FB.init connect using the JS no problem ie.
<script>
// initialize the library with the API key
FB.init({
apiKey: '9999999999999999999999999999',
session : <?php echo json_encode($session); ?>,
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
$('#login').bind('click', function() {
FB.login(handleSessionResponse);
});
I can test if its working by reloading the page an using the following script I can see the response session.
FB.getLoginStatus(function(response) {
if (response.session) {
console.log(response.session)
} else {
// no user session available, someone you dont know
}
});
But the PHP SDK is not picking up the session.
ie
$facebook = new Facebook(array(
'appId' => '9999999999999999',
'secret' => '9999999999999999999999999999999',
'cookie' => true,
));
$session = $facebook->getSession();
The javascript is creating a cookie but its not being found by the session.
Any suggestions to what I am doing wrong.
Hope you can help.
For whatever reason the problem has resolved itself.
May have been a server issue