I currently have the facebook js sdk to login to the site and then I want to use the PHP sdk for everything else. How can I pass the accessToken to the PHP SDK to allow me to do this? I want to pass it to a PHP script at a different url, so for example I login at /login/ and then open up a modal box to /facebook/?accessToken=gfdhjsfghjkfgdh or what ever.
http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
Please check this link.
A sample code may look like this,
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//got the token
var accessToken = response.authResponse.accessToken;
//send it to php via _GET
window.location = "/facebook/?accessToken=" + 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.
}
});
You can get the accesstoken then send it to php.
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 tried to implement facebook login in local,i used below code in my website
<html>
<head></head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '{your-app-id}',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Here we subscribe to the auth.authResponseChange JavaScript event. This event is fired
// for any authentication related change, such as login, logout or session refresh. This means that
// whenever someone who was previously logged out tries to log in again, the correct case below
// will be handled.
FB.Event.subscribe('auth.authResponseChange', function(response) {
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
// The response object is returned with a status field that lets the app know the current
// login status of the person. In this case, we're handling the situation where they
// have logged in to the app.
testAPI();
} else if (response.status === 'not_authorized') {
// In this case, the person is logged into Facebook, but not into the app, so we call
// FB.login() to prompt them to do so.
// In real-life usage, you wouldn't want to immediately prompt someone to login
// like this, for two reasons:
// (1) JavaScript created popup windows are blocked by most browsers unless they
// result from direct interaction from people using the app (such as a mouse click)
// (2) it is a bad experience to be continually prompted to login upon page load.
FB.login();
} else {
// In this case, the person is not logged into Facebook, so we call the login()
// function to prompt them to do so. Note that at this stage there is no indication
// of whether they are logged into the app. If they aren't then they'll see the Login
// dialog right after they log in to Facebook.
// The same caveats as above apply to the FB.login() call here.
FB.login();
}
});
};
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// Here we run a very simple test of the Graph API after login is successful.
// This testAPI() function is only called in those cases.
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
}
</script>
after i login to my website , facebook login button is appering.but when i click on login button, i is showing URL error
I tried all below url to set Site URL in facebook dashboard
but still am getting same error.
am using wamp(php)
can any one help me, what is the url ia have to set as site url in facebook dashboard to it should work locally??????
Here is two solutions to run your facebook application in your localhost..
Running Facebook application on localhost
http://ankurm.com/blog/using-localhost-for-facebook-app-development/
also you have to enable curl extension in your php..
After proving your App Id for facebook , use redirect_url and set it to local address.
Im using the javascript SDK of facebook in the frontend:
jQuery("#pct_fbbutton").live("click",function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log('Conected');
FB.api('/me/likes', function(response) { user_likes = response;
FB.api('/me', function(response) { user = response;
send_server(user, user_likes);
});
});
} else if (response.status === 'not_authorized') {
console.log('not_authorized');
login();
} else {
console.log('not_logged_in');
login();
}
});
});
As you can see, after the user is login with facebook ill send two objects via AJAX to a php script (using the function send_server).
I can access in the backend the currently generated token with $facebook->getAccessToken(), but as I know this is retrived from a cookie made by the javasript sdk, considering that all frontend data can be hacked, using the token how can ensure that the user data is valid on php?
The answer is to perform the graph calls with PHP instead of JavaScript, especially if the only purpose of your client-side script is to send it to the server;
Doing the data gathering on the server is the only practical way you can be sure that the data has not been tampered with, assuming you do proper https certificate checking.
The validity of the access token is also easy, because Facebook will return an error if the provided access_token value is invalid.
Once you retrieve the access_token in the back end, try to fetch the user's profile. If the fetch was successful, then the client provided you with the correct access_token and you should save it. Something like the below example should work, but you can find many more examples:
<?php
$facebook = new Facebook(array(
'appId' => $initMe["appId"],
'secret' => $initMe["appSecret"],
));
$facebook->setAccessToken($initMe["accessToken"]);
$user = $facebook->getUser();
if ($user) {
$user_profile = $facebook->api('/me');
print_r($user_profile);
}
?>
I'm having some troubles with the Facebook API, I am requesting permission for some information of the user by Javascript:
FB.login(function (response) {
if (response.authResponse) {
// authorized
} else {
// canceled
}
}, {scope: 'email,user_birthday,user_location'});
Now I want to get the user's information (when he is authorized) by PHP:
$facebookUser = json_decode(file_get_contents('https://graph.facebook.com/' . $this->data['userid'] . '?access_token=' . $this->oathtoken . '&fields=id,name,location,gender,email,picture,birthday,link'));
All working great, except that the API is not giving the user's birthday back. Even when I set my birthday privacy settings on public it won't show up.
So:
echo $facebookUser['birthday']; // Gives an error, since this key does not exists
Does somebody have an idea how to fix this?
You are logged in on the client side but php is executed on the server side so you receive only the basic information of an user object.
If you logged in on the server side and have the permissions so you can get the birthday simply with:
echo $facebookUser['birthday'];
Most probably you didn't receive approval to request user_birthday from FB.
You can't get user_birthday unless FB reviews your FB app.
Only the following permissions may be requested without review: public_profile, user_friends and email
(See: https://developers.facebook.com/docs/facebook-login/review/what-is-login-review)
Without review you can request only age_range, but not user_birthday
FB.login(function (response) {
var user_birthday = response.user_birthday;
console.log(user_birthday);
if (response.authResponse) {
} else {
// canceled
}
}, {scope: 'email,user_birthday,user_location'});
why don't you use serverside auth if you would like get FB info in server side?
if you are ok with clientside authentication, above should work.
Given that a Facebook user has logged in at some point in your Facebookapp (using fb.login) and that user has been saved in the database. How can you let the user re-authenticate with you app again after the accesstoken has expired (fb.api('/me') fails).
The signed request holds the user id, but how do you log in the user from there?
I'm using the PHP sdk and I basicly check with FB.api('/me') right in the beginning to either direct to a welcome page or the users page. But FB return false in some cases, usually after a day or 2. So I started to think it was because of the Accesstoken has expired. I have no clue how to re-authenticate, I only have knowledge that the user id still resides in the signed request.
Put following code in your javascript...it will open login popup if user is not logged in
FB.getLoginStatus(function(response) {
if (response.authResponse) {
fbUserId = response.authResponse.userID;
token = response.authResponse.accessToken;
} else {
FB.login(function(response) {
if (response.authResponse) {
fbUserId = response.authResponse.userID;
token = response.authResponse.accessToken;
}
else {
console.log('User cancelled login or did not fully authorize.');
}
});
}
},true);
Use the Javascript SDK to prompt the user to login via Facebook:
https://developers.facebook.com/docs/reference/javascript/FB.login/
Alternatively, you could try storing the code returned by Facebook during server-side auth and use it to request a new token when the user returns.