How to authenticate Facebook User after receiving response.status === 'connected'? - facebook

Perhaps I am going about this the wrong way but I have a website that allows facebook login.
If the user has already registered on my website
and is logged into facebook but not logged into my site
when visiting the login page i check for their facebook login status and get response.status === 'connected' via-
FB.Event.subscribe('auth.authResponseChange', function (response)
{
if (response.status === 'connected')
{
var s = JSON.stringify(response.authResponse);
LogMeIn(s, function(response)
{
HandleAjaxError(response, function(msg)
{
window.location = '/_/';
});
});
}
}
I then want to pass their authResponse object to the server and confirm that this userid works with this token before I log them in as this user
I have read to simply grab the json contents of -
https://graph.facebook.com/{userID}?access_token={accessToken}
and if it does not return an error then it is good! But when testing this method I noticed that the same access_token worked for two different user ids (meaning it did not return an error for the userid that was not logged in on my computer). Instead it returned the facebook user object with name , location etc.
This really surprised me, as I expected the access_token to work only with a single user id.
In an effort to prevent someone from simply changing the user id before continuing the script I need to authenticate via server side. What is a way to accomplish this?
Proof, go to these links to see profile information
My profile-
https://graph.facebook.com/1233822590?access_token=CAACCBJJZBgjABAOGmvmsou8gMYGulLHTgAr5ZCHZAU7pKEp0cMAeX8r4qHLpiVuZCOT1v0ulMZAxX5YfLJkcZBr9l6qJQoPxWS5Fs5ndohDnH6ZAPPfZCZCTQtwWgAZAg6I1PAOIpdtCc0OUaMmBZAvGiMm9gQhmNXRbocZD
Another userid with same access_token-
https://graph.facebook.com/100000116781159?access_token=CAACCBJJZBgjABAOGmvmsou8gMYGulLHTgAr5ZCHZAU7pKEp0cMAeX8r4qHLpiVuZCOT1v0ulMZAxX5YfLJkcZBr9l6qJQoPxWS5Fs5ndohDnH6ZAPPfZCZCTQtwWgAZAg6I1PAOIpdtCc0OUaMmBZAvGiMm9gQhmNXRbocZD

Nothing to be surprised. You can fetch the basic details of any user of the facebook using the access token of any user of the facebook.. So this isnt really good way to validate the token. Moreover, that confirmation of token part isnt required.
If you want the authorization through server side go through.this link

Related

Initiate login for custom stories

I have created a custom story to be posted on facebook timeline when user clicks on a share button.
While i was logged into facebook, I could successfully post on timeline using the following code
function postLike() {
FB.api(
'https://graph.facebook.com/me/og_pricepan:compared',
'post',
{ product: objectToLike,
privacy: { 'value': 'SELF'}
},
function (response) {
if (!response) {
alert('Error occurred.');
} else if (response.error) {
document.getElementById('result').innerHTML =
'Error: ' + response.error.message;
} else {
document.getElementById('result').innerHTML =
'<a href=\"https://www.facebook.com/me/activity/' +
response.id + '\">' +
'Story created. ID is ' +
response.id + '</a>';
}
}
);
Now, when the user is not logged into facebook, I get the following error:
Error: An active access token must be used to query information about the current user.
Shouldn't the login window get open by itself asking the user to login into facebook or I need to do something on my end to handle this situation?
Also, do i need to submit my application for review before users can create custom stories from my website to their timeline?
Shouldn't the login window get open by itself asking the user to login into facebook or I need to do something on my end to handle this situation?
No. You need to explicitly login the user by following the Facebook Login Flow to request an access token
Also, do i need to submit my application for review before users can create custom stories from my website to their timeline?
Yes and No. No, because it's not like you will have someone from Facebook Support Team going through your app to make sure your app ticks all the boxes. Yes, because you will need to register your app with Facebook. So, technically all you need to do is register with Facebook as a developer and register your app in order to get an app secret and API key. You can have your app in "Sandbox mode", create test users and test your integration with Facebook before you publish it live. There's few requirements you need to meet before publishing it, such as providing set of logos of a specific size, etc. Here's a blog explaining part of the process, but really, the process is very straight-forward and you should be able to get through easily by yourself.
Now, the error you are getting says it all. There's no user logged in to facebook. The endpoint you are trying to post to, requires a active valid access token, if it doesn't exist then there's no context, no user authenticated and you need to explicitly authenticate the user by invoking the login dialog...
FB.login(function(response) {
if (response.authResponse) {
// The person logged into your app
} else {
// The person cancelled the login dialog
}
});
If you need to know whether a user is logged in or not, you can follow to simple approaches:
1.By invoking the FB.getLoginStatus function
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
}
else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
}
else {
// the user isn't logged in to Facebook.
}
});
2.Or, by subscribing to the auth.authResponseChange event when initializing the framework and setting the status option to true
There's a full-legged tutorial on Facebook Developers Site for Javascript SDK explaining both approaches.
Hope it makes sense

Loose req.session when trying to get more FB privileges via everyauth

I've been doing user authentication with everyauth and Facebook and all works well. Now, I want to integrate an ability to post to Facebook. Since my app asks only for email scope when users first login, I'll need to get a larger FB scope, and am trying to follow the FB guidelines and only ask for this additional scope when I need it.
I added the following code to my everyauth configuration as per the docs:
everyauth
.facebook
.appId(conf.fb.appId)
.appSecret(conf.fb.appSecret)
//TODO add custom redirect for when authentication is not approved
.scope(function (req, res) {
console.log('Setting FB scope');
console.log('Session: ' + util.inspect(req.session));
var session = req.session;
switch (session.userPhase) {
case 'share-media':
return 'email,user_status';
default:
return 'email';
}
})
All is well when an unauthenticated user logs into the application. The problem is that when I want to "up the ante" on FB scope, which I do by setting req.session.userPhase to 'share-media', and then present a link to /auth/facebook to confirm they want to allow posting to FB. When this happens, I get an error that req.session is undefined from the above code (all of req is undefined).
I assume this is since a previously logged-in user is essentially re-authenticating, but isn't that how I would get more scope from Facebook? Am I going about this the wrong way?
Thanks!!!

Login with facebook not working, cases refresh loop

On one of my websites, we have implemented the Login with facebook script. It was working fine till yesterday but suddenly there seems to be a problem with the script. If I am already logged in facebook, my website's page keeps on refreshing. If I log out of facebook then the refresh stops.
If this is facebook's script problem then I think there would be many other people who are facing this problem. Is any one here also facing this problem ?
please share and provide the solution if there is any.
Thanks
Ishan
We had the same issue and we started using Fb.getLoginStatus instead of FB.Login and redirected the users based on their status to the login page manually.
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
FB.api('/me', function (userDetails) {
LoadRegForm(userDetails);
});
} else if (response.status === 'not_authorized') {
Rediret to facebook oauth page
top.location.href = 'https://www.facebook.com/dialog/oauth?client_id=<%= ConfigurationManager.AppSettings["fbappid"] %>&redirect_uri=<%= ConfigurationManager.AppSettings["fbcanvasurl"] %>&scope=email,user_birthday,user_education_history';
} else {
// the user isn't logged in to Facebook.
top.location.href = 'https://www.facebook.com/dialog/oauth?client_id=<%= ConfigurationManager.AppSettings["fbappid"] %>&redirect_uri=<%= ConfigurationManager.AppSettings["fbcanvasurl"] %>&scope=email,user_birthday,user_education_history';
}
You can even call the FB.Login function in the two else blocks instead of the redirect.

Facebook Ask new permissions

I've an application that only asks for "user_about_me". Now I want to ask for new permission (publish_stream) but the response object returns "connected" if the user ignores the new permission. Because I want to post to the user's wall I'll get an error when posting to the user's wall "The user hasn't authorized the application to perform this action".
How can I do this?
I'm using Javascript SDK.
Basically you have to handle all the possibilities for user permissions/authorization when a user logs in. Here is a simplified working example from some FB integration I have done:
FB.Event.subscribe('auth.login', function(response) {
if(response.status === 'connected'){
FB.api('/me/permissions', function(resp) {
if(resp.data[0].publish_stream){
//User has permissions and authorization
}
else{
//User has not enabled publish stream, ask them to enable permission
}
}
}
If they have the permissions, I show them their avatar/username and some other options. If not, I present a link that asks them for the required permissions when clicked.

Facebook Connect require login for some links

Is there any fb tag i can use to wrap around my html anchor tag so that if the user isn't logged in, they will get prompted to login before getting access to the link?
I'm using python/django in backend.
Thanks,
David
You simply need an if statement to check whether a facebook session exist or not. If not redirect them to the login page.
-Roozbeh
First I think you must create a Facebook App.
Second: if you are programming in PHP, you should use the PHP SDK.
See: https://developers.facebook.com/docs/reference/php/
Third: Use getUser method:
https://developers.facebook.com/docs/reference/php/facebook-getUser/
I'm almost sure that getUser will return 0 if the user has not accepted your app, so IMO it's not the best method to find the user connection status on Facebook.
Also, getLoginStatusUrl could help, with this function you could make redirections based on the user status on Facebook, and think of a mechanism to show or not the contents based on parameters and session variables (it's an idea).
See: https://developers.facebook.com/docs/reference/php/facebook-getLoginStatusUrl/
Hope that helps.
Using the JavaScript API you'll want to use FB.getLoginStatus to wrap around the anchor tag. See https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
Example from that page:
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// the user is logged in and connected to your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
//but not connected to the app
} else {
// the user isn't even logged in to Facebook.
}
});
Note: I would simply make this call up front and set my own JS variable boolean on the response so I didn't have to use the FB API call again. Then wrap any dependent code with a simple JS boolean test.