OAuthException when doing a facebook query - facebook

I get the following error when trying this URL (just pasting it in a browser to check for output):
https://graph.facebook.com/search?q=London&type=event&access_token=ACCESS_TOKEN
{ "error": {
"message": "(#200) Must have a valid access_token to access this endpoint",
"type": "OAuthException",
"code": 200
}
}
I got the ACCESS_TOKEN by following this guide. What am I doing wrong?
Solution
Thanks to Rahil Arora for the tip. Here is how I printed out my access token:
I put this on my private website. After I set the public URL of the FB app to point to that webpage, I simply clicked on the "login" button. Then there was a popup that allowed my app to access my personal data, and voila! It printed out the access token ;)
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://connect.facebook.net/en_US/all.js"></script>
</head>
<body>
<button id="login">Login to FB</button>
<p>Access token: <span id="token"></span>
<script>
$(function() {
FB.init({
appId : 'APP-ID', // App ID
channelUrl : '', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true
});
FB.Event.subscribe('auth.authResponseChange', function (response) {
if (response.status === 'connected') {
$('#token').html(response.authResponse.accessToken);
}
});
$('#login').click(function(e) {
FB.login();
});
});
</script>
</body>
</html>

You are using an App Token. What you really need for the request is a User Access Token.
The search API documentation says that:
Searches across page and place objects requires an app access token.
All other endpoints require a user access token.
Since you are searching for an event, you need a User Access Token. You can find more details about generating User Access Tokens here.
To test you queries, you can use the Graph API Explorer. It provides you with a User Access Token by default for testing you queries.

As the error message stated, the provided access token is not valid. If you provide an access token, it must be valid. Otherwise you get an error. If you want read public data w/o any token, leave the access token away entirely.
access token are only valid for a limited period of time. They expire after some time, which can be days or hours. You need to check and ask for a new access token, if it is expired. Usually you get a different and particular error code on this.
The user, which owns the data you want access, must have granted access to your app first. That's how you retrieve the access token by OAauth. Once he revokes this grant, your access token is invalidated. The user can do this at any time w/o your notification, leaving you alone with the above error message.
Bottom line: you need to dig in to that and investigate further what actually has happened:
you actually have an invalid (never valid) token
your token was valid but has been revoked
...

Related

Doubts about Security in Login for Web with Facebook Oauth JavaScript SDK that send ACCESS TOKEN to server

I have doubts about security of my process of authentication oauth with facebook..
I use login for web with javascript sdk with fb button:
I get an Access Token successfully and pass it to server(calling check_facebook_session.php) to make API call to Facebook Provider..
In the following code there is also the log in console of access token.
Everything works!!! on the server I use the php sdk to call the API REST with APPID, APPSECRET and ACCESS_TOKEN:
**
Now my question, have I a security problem?
Is a bad idea to pass the token to the server?
The token that is visible on the client can be used WITHOUT APP SECRET to get information about the user logged?
**
Note: Google+ Sign-In for server-side apps Implementing the one-time-code flow with step:
- Include the Google+ script on your page.
- Add the sign-in button to your page.
- Sign in the user.
- Send the authorization code to the server.
as explained in: https://developers.google.com/+/web/signin/server-side-flow
Unlike facebook google in the js client return a CODE, not an ACCES TOKEN and the server receive and use it to request ACCESS TOKEN.
Thanks..
Following is the javascript code for facebook:
window.fbAsyncInit = function() {
FB.init({
appId : FACEBOOK_APP_ID, // App ID
status : true, // check login status
cookie : false, // enable/disable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.Event.subscribe('auth.authResponseChange', function(response)
{
if (response.status === 'connected')
{
var accessToken = FB.getAuthResponse()['accessToken'];
console.log(accessToken);
$.ajax({
type: 'POST',
url: check_facebook_session.php,
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
processData: false,
data: 'token=' + accessToken,
success: function(result)
{
if(result == 'SUCCESS'){window.location.href = fb_callback_url}
},
error: function(xhr)
{
alert('Request Status: ' + xhr.status + ' Status Text: ' + xhr.statusText + ' ' + xhr.responseText);
}
});
}
else if (response.status === 'not_authorized')
{
FB.login();
}
else
{
FB.login();
}
});
};
// Load the SDK asynchronously
.......
}(document));
I did some testing and came to the conclusions that I hope can be useful.
In Facebook SDK for JavaScript it automatically handles access token storage and tracking of login status, so apps using it do not need to create their own mechanisms for doing so, and can proceed to making API calls.
The system seems safe because I believe that the callback url of the call is the site that host the page and configured between those of the facebook application, so I can change the application id in the javascript code but the sdk response with error message and get the user's token pretending to be another application. This was already obvious to those who know the flow :-)
Passes the token to the server is definitely a bad idea because it can be snorted and used by simply calling https://graph.facebook.com/me?access_token=... to get user information, In the different flow of google the token is not passed but is passed the code necessary to obtain it.
The best solution to use advantage of client and server is it:
Used in conjunction with the Facebook SDK for JavaScript,
the PHP SDK can share user sessions seamlessly across the client and server.
If people are logged in with Facebook and have authorized your app,
the JavaScript SDK can pick up the user session and persist this in a cookie,
which the PHP SDK reads without any intervention on the developer's part.
To enable this functionality, ensure that when you embed and initialize the JS SDK,
you set both the status and the cookie parameters of the object passed to FB.init() to true.
Regards..
i think it is secure because the user's data is only returned with connected status after user authentication with facebook.
https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
I have followed Facebook example on getting access token by using $fb->getJavaScriptHelper();
https://developers.facebook.com/docs/php/howto/example_access_token_from_javascript
$helper = $fb->getJavaScriptHelper();
$accessToken = $helper->getAccessToken();
echo $accessToken->getValue();
P.S. Add try{} catch() {} blocks, as in Facebook example for error handling.

trying to get app access token

I tried to get an app-access-token for my facebook app with this code:
APP_ACCESS_TOKEN = FB.api(
"oauth/access_token",
{client_id: APP_ID, client_secret: APP_SECRET_CODE, redirect_uri: uri},
function(response){
console.log(response);
});
which should be like:
GET https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&redirect_uri=uri
but i get an error:
code: 1
message: "Missing authorization code"
type: "OAuthException"
What is the authorization code and how can i get it?
Obtaining an App Access Token
To obtain an App Access Token, invoke the following HTTP GET request:
GET https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
The API will respond with a query-string formatted string of the form:
access_token=YOUR_APP_ID|YOUR_APP_ACCESS_TOKEN
Reference: http://developers.facebook.com/docs/opengraph/howtos/publishing-with-app-token/
https://developers.facebook.com/docs/howtos/login/login-as-app/:
“Because it requires you to include your App Secret you should not attempt to make this call client-side as that would expose this secret to all your app users. It is important that your App Secret is never shared with anyone. For this reason, this call should be performed server-side”
And for the app access token, it’s the same – you should never use it client-side, because every user could spot it there and then start using it to perform actions on behalf of your app (or change many of your app’s settings).
If you have a server-side part to your application, you can simply “build” the app access token there yourself, concatenating app id and secret with a pipe symbol, app_id|app_secret.
check if users of the node.js or the JAVASCRIPT.
getLongLiveToken: function(data){
FB.api('oauth/access_token', {
client_id: data.client_id, // FB_APP_ID
client_secret: data.secret, // FB_APP_SECRET
grant_type: 'fb_exchange_token',
fb_exchange_token: data.access_token // USER_TOKEN
}, function (res) {
if (!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
} else {
var accessToken = res.access_token;
if(typeof accessToken != 'undefined'){}
}
});
}
I'm not sure that exposing the APP client secret in the code is a good idea, you can take the APP token from Facebook tool "Access Token Tool" just copy the token to your code for any use https://developers.facebook.com/tools-and-support/
You can also use this POST endpoint without generating the token, just be sure its being called from the server not client-side where the app_secret is exposed to public:
https://graph.facebook.com/?id={url}&scrape=true&access_token={app_id}|{app_secret}

Different Facebook access token JavaScript SDK

I'm quite confused with the access token from facebook..here is how I obtain the user's access token and use it to get data from graph API
window.fbAsyncInit = function() {
FB.init({
appId : 'app ID',
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
FB.getLoginStatus(getStatus);
FB.Event.subscribe('auth.authResponseChange', getStatus);
function getStatus(response) {
if ( response.status === 'connected' ) {
var accessToken = response.authResponse.accessToken;
console.log("accessToken = " + accessToken);
$.ajax({
dataType : "jsonp",
type : "GET",
url : "https://graph.facebook.com/me/albums?access_token=" + accessToken,
success : function(data) {
$.each(data, function(index, value) {
console.log(index + ": " + value);
})
}
});
}
}
};
However, I always get an empty data. After I visit the graph API documentation here: https://developers.facebook.com/docs/reference/api/ and click on one of the graph links, I notice that the access token generated there is always different from what I retrieve from my code. For example, the current access token in the graph api documentation is
"AAAAAAITEghMBAMwuyHZCO3VOAvCm9hHpaZC9PGV9238ixsZB7zSfuplZBTZCLRj6cEViZADJlVcjOfInwvcbhqu3XBF1w4ZAxvPbexcGQZAYzb4bHAKsMbLF"
and the one in console log is
"AAAG0ZCFantJ8BAAFcMdDOyDyT4OBtjrvULEaS2o94gZAU7U1xITaogFXCZBghQP8G9bjEh3XSCATQOZCUSZCuNWFvEfypIAmcz9bkbk5qRBlHUZAOE4guW"
I think that I may have done this the wrong way. Can anyone help explain to me how to retrieve data from graph API in a correct way?
Any kinds of help will be appreciated. Thanks in advance :)
Run this URL with your authToken first:
https://graph.facebook.com/me/permissions?access_token=USER_ACCESS_TOKEN
You'll almost certainly only see basic permissions in the response, which is why you aren't getting the data from your call to the user's album.
You'll then want to run your user through the Authentication Process, making sure you request the permissions you need (probably 'user_photos' in your case).
More info is available in those two links. Good luck!
access token will never be the same. So that behaviour is correct.
Back to your problem , I think its mostly scope related issue.
I had developed a application using facebook c# sdk, In that application i did it like this:
when a post is to be submitted , redirect the user to facebook (with some parameters like appid, app-secret, auth-token and
redirect-url);
Facebook will ask the user to login with his credentials.
When the user is logged in, facebook will redirect back to the redirect-url. (with the authtoken and a new auth-code).
Then we should use this auth-code, app-id and app-secret and obtain the user-access-token. (This is done by doing a rest api call to the
url
https://graph.facebook.com/oauth/access_token?client_id=client_id&redirect_uri=redirect_uri&client_secret=client_secret&code=auth-code
This will return the user-token and expiry time for the token
And then we can post using this user-access-token to the fb.
Initially i had misunderstood the auth-code and used it as the user-access-token, and i always got the result as unauthorised token .
Please check whether this will help you or not.

Facebook login - access_token

I'm trying to login users to my web page via facebook, and after they login via facebook i want to store their id (and some other informations) in db, so when someone came back, he/she will be redirected to their profile (which script was created first time).
So, i want to ask it is ok to use java sdk (facebook) for getting access token, and then use that token in .php via ajax..
So for example in javascript would be something like this:
FB.init({
appId: 'xxxxxxxxxxx',
status: true,
cookie: true,
xfbml: true,
oauth: true
});
//login
FB.login(function (resp) {
if (resp.authResponse && resp.authResponse.userID) {
var accessToken = response.authResponse.accessToken;
//here will be call for ajax with accessToken parmetar
}
});
});
After that .php (sdk php facebook) will use that access token to get information about user.
Probably you will ask why i dont just send resp.authResponse.userID via ajax and store it in db. Answer is that, someone can use "java in fly" and store users with different id-s. I hope that getting information on .php (server) side with access token will not let this happen..

Facebook OAuth 2.0 mechanism does not always redirect to redirect_uri when pressing cancel

I have an issue with the Facebook OAuth 2.0 mechanism. In principle all is working well, except for one thing: when a user is redirected to the page where he should authorize/permit the app but is clicking 'Cancel', about half of the time he is redirected to the page I specified in the redirect_uri (correct behaviour - so I redirect him to a page explaining why we need the permissions) and about half the time he is ending up on the FB homepage (wrong behaviour). I just can't figure out what I am doing wrong. This is roughly what I am doing:
window.fbAsyncInit = function()
{
FB.init({
appId : <appid>, // App ID
channelUrl : 'http://www.mydomain.com/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
// Additional initialization code here
FB.getLoginStatus(function(response)
{
//console.log('getLoginStatus response: ',response);
if (response.authResponse)
{
//user is already logged in and connected
top.location.href='http://apps.facebook.com/<appname>';
}
else
{
//app is not authorized or user is logged out
var redirectURL = 'http://www.facebook.com/dialog/oauth/?client_id='+client_id+'&scope='+scope+'&redirect_uri='+encodeURIComponent('http://apps.facebook.com/<appname>')+'&response_type=token';
top.location.href = redirectURL;
}
});
};
Any idea what I am doing wrong? As said in the opposite case, where the user does accept to authorize the app al works just fine. I am still working in sandbox mode and have not yet bought an SSL certificate which is why I am still referring everywhere to http instead of https.
Thanks!
P.S. This strange behaviour never happens when the user clicks 'Don\'t allow' when asking for optional permissions the following times the user accesses my app. For example, the user logs in for the first time and authorizes the app, but does not allow for the optional permissions. Facebook then redirects him to the redirect_uri and gives me an access_token, so I redirect the user to the app (so far so good). The next time when the user accesses the app, I detect that he has authorized the app, but that I don't have all the optional permissions I want, so I redirect him again to the OAuth 2.0 mechanism. This time the user AGAIN doesn't allow the optional permissions and Facebook ALWAYS redirects the user to the redirect_uri which is the expected behaviour.