Facebook JS connect unsupported browser IE mobile - facebook

I am getting error "unsupported browser: IE" when I am trying to login using facebook in windows mobile device(Lumia 800). Is there any way it can be fixed or facebook have to do fixes in their script. Or any other workaround can be done for this issue? Please suggest.

I have faced this problem as well with a big project I did for Microsoft. I needed to oath with Facebook on windows mobile devices, and got the same error. This is how I solved it:
Generally there are two ways to oath with javascript - the simple way (which generates this error) described here:
https://developers.facebook.com/docs/javascript/quickstart
and the manually build login flow described here:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
Here is a quick explanation of what you have to do for the second option:
1) Load 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));
2) On page load check for access_token. If the user didn't login, there will be no access token. if the user did, there will be access token appended to the URL as a query but with '#' instead of '?'
I used this function:
function getUrlVars()
{
var query = '#';//normally ?
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf(query) + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
Now determine if you got the access_token:
var urlString = getUrlVars();
var hasAccess=false;
var userToken;
if(typeof(urlString)!='undefined' && typeof(urlString.access_token)!='undefined'){
hasAccess=true;
userToken=urlString.access_token;
}
if user has access redirect them to the same (or other) url with the app id, access token and response type:
var appID = 'your app id';
if(!hasAccess){
$('#login').on('click',function(){
var login_redirect_uri = 'http://www.yourpage.com/';
var login_response_type = 'token';
var loginURL = 'https://www.facebook.com/dialog/oauth?client_id='+appID+'&redirect_uri='+login_redirect_uri+'&response_type='+login_response_type;
window.location.replace(loginURL);
});//login-click
}
3) if there is no access token in the url query, use a server side service (we will build below) to validate the token
var tokenValidate = 'https://titan-img-gen.aws.af.cm/toeknValidate.php';
$.ajax({
type: 'GET',
url: tokenValidate,
crossDomain: true,
data:{
token:userToken
},
dataType:'json',
success: function(validateData){
if(validateData.error){
showError();
}else{
username = validateData.username;
firstname = validateData.firstname;
lastname = validateData.lastname
//continue your code
}
},
error: function (responseData, textStatus, errorThrown) {
showError();
}
});
4) Server side service (PHP)
a)generate app token: https://developers.facebook.com/docs/facebook-login/access-tokens/
b)same origin resolution might be needed:
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
c) define app_token :
$app_token='*******';
d)check for token parament in get
$reponse = array();
if(!isset($_GET['token']) || $_GET['token']==NULL ){
$reponse['error'] = true;
}else{
$user_access_token = $_GET['token'];
//continue here...
}
e) use facebook graph service to debug token
$fbDebug = "https://graph.facebook.com/debug_token?input_token=$user_access_token&access_token=$app_token";
f)get the json file, decode it and get the user_id from it. you can then retrieve more info from Facebook easily
try{
$fbResult = file_get_contents($fbDebug);
$fbResultDecode = json_decode($fbResult);
if(isset($fbResultDecode->data->error)){
$reponse['error'] = true;
}else{
$user_id= $fbResultDecode->data->user_id;
$userJSON = file_get_contents("https://graph.facebook.com/$user_id");
$userInfo = json_decode($userJSON);
$reponse['username'] = $userInfo->username;
$reponse['firstname'] = $userInfo->first_name;
$reponse['lastname'] = $userInfo->last_name;
}
}catch(Exception $e){
$reponse['error'] = true;
}
g)return the JSON
header('Content-Type: application/json');
echo json_encode($reponse);
Bada-Bim-Bada-Boom
I lied, it wasn't a quick explanation... but I hope it will save you some time!!!
Tomer Almog

Related

Facebook page access token for the page I am admin of

I am using the Facebook JS code for retrieving a list of pages of which I am assigned to as an admin. I get list of all such pages but one page is somehow not showing up. I have checked all the permissions and roles, using proper app id, also the app is showing active on that page but still somehow it is not showing up in the list and I need that page for getting page access token. Also I am using manage_pages permissions in Facebook JS function.
So can someone please suggest a probable reason for the page not showing up in the list. The code I am using is below (which is completely facebook code except my app ID).
<script>
window.fbAsyncInit = function()
{
FB.init({
appId : 'xxxx6xx89xx5xxx', // app id is correct i have checked
xfbml : true,
version : 'v2.12'
});
};
(function(d, s, id)
{
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
function subscribeApp(page_id, page_access_token)
{
console.log('Subscribing page to app! ' + page_id);
FB.api(
'/' + page_id + '/subscribed_apps',
'post',
{access_token: page_access_token},
function(response)
{
console.log('Successfully subscribed page', response);
}
);
}
// Only works after `FB.init` is called
function myFacebookLogin()
{
FB.login(function(response)
{
console.log('Successfully logged in', response);
FB.api('/me/accounts', function(response)
{
console.log('Successfully retrieved pages', response);
var pages = response.data;
var ul = document.getElementById('list');
for (var i = 0, len = pages.length; i < len; i++)
for (var i=0; i < response.data.length; i++)
{
var page = pages[i];
var li = document.createElement('li');
var a = document.createElement('a');
a.href = "#";
a.onclick = subscribeApp.bind(this, page.id, page.access_token);
a.innerHTML = page.name;
li.appendChild(a);
ul.appendChild(li);
}
});
}, {scope: 'manage_pages'});
}
</script>
<button onclick="myFacebookLogin()">Login with Facebook</button>
<ul id="list"></ul>
Tell me if i missed something in the comments, but afaik it can only be those things:
You have more than 25 Pages, so you need to use the limit parameter or paging. Test it with the limit parameter: FB.api('/me/accounts', {limit: 100}, function(response) ...
You don´t have sufficient permissions for the Page
It´s a bug and you should report it to Facebook

Best Practices: Interaction between Facebook Login and Symfony2

I wounder what is the best way to implement a login/registration with facebook in my symfony2 application.
What i want: I want to secure the whole application (except /login). On login page i will provide a facebook login button, like this
<fb:login-button show-faces="true" width="200" max-rows="1"></fb:login-button>
If a user authenticates with facebook, i want to look if there is already an user in the database with this fb-id, then set this user as the actual authenticated symfony user. if user not exist in database, "register" it and write it to database (and set as symfony secure user).
what i already have is this:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '...',
status : true, // check login status
cookie : true, // enable 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 params = new Array();
params['accessToken'] = response.authResponse.accessToken;
params['expiresIn'] = response.authResponse.expiresIn;
params['signedRequest'] = response.authResponse.signedRequest;
params['userID'] = response.authResponse.userID;
postToUrl("{{ path('_user_checkfbuser') }}", params);
}
});
};
// 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));
function postToUrl(path, params, method) {
method = method || "post"; // Set method to post by default if not specified.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
for(var key in params) {
if(params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
return true;
}
</script>
and my controller action:
/**
* #Route("/user/checkfbuser", name="_user_checkfbuser")
*/
public function checkFBUserAction()
{
if($this->get("request")->getMethod() == "POST"){
$request = Request::createFromGlobals();
$accessToken = $request->request->get('accessToken');
$expiresIn = $request->request->get('expiresIn');
$signedRequest = $request->request->get('signedRequest');
$userID = $request->request->get('userID');
$user = $this->getDoctrine()->getRepository('...:User')->findOneBy(
array('id' => '1')
);
$token = new UsernamePasswordToken($user, null, 'secured_area', $user->getRoles());
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_main',serialize($token));
return $this->redirect($this->generateUrl('_frontend_index'));
}
return false;
}
What is the usual way to implement such a behaviour?
If you want to do the facebook authentication manually follow the instructions on:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.1
You will need to understand what the access token does.
The login flow should be,
Initiate oAuth request from Facebook with a redirect uri via a redirect(php)/location assign(javascript)
An authentication dialog will popup for user to enter login details (this step will ensure the user knows the username and password of their facebook account).
Capture redirect to redirect_uri to symfony action to process
Use returned code (not access code) , request_uri and your app secret to request from Facebook an access_token. This step is to ensure the request is indeed from your application (please keep your app secret hidden - do not show in any client side code).
If successful, Facebook will return a usable access token to be used for future requests to the Graph API (although it has an expiry window).
Use your access token to get email/username data etc to match with Symfony user account.
Authenticate user with Symfony like you normally do.
FosFacebookBundle is for this purpose. It integrates the Facebook PHP SDK, and automates the register/login process between facebook and symfony.
I used it once, but it is a littlebit hard to customize if you need some more advanced logic. In that case I just used the FacebookSdk directly.If you need help with that, tell me:)

Facebook SDK - Using JS to Auth and PHP for the rest?

I am trying to use the Facebook PHP and JS SDKs together in order to create a web app that will double as a canvas app. In the current setup I am experiencing issues when the page is left or a while and the system reverts back to the login screen. It is important to not I am using a dynamic domain mapper and there are a few possible URLs /dev/, /dev/pool/, /dev/pool/edit/, etc. that the user might visit and experience the app.
I read around and found that authorizing with the JS SDK is the correct method (I could be wrong?) and then using the PHP SDK to sort through everything else will work just find, gaining the access token naturally.
I know this is something wrong with my authentication setup, as I see it reload sometimes, I also get stuck with a login button that doesn't do anything if I am on a sub page, and if I don't touch the site for a couple of minutes the system tries to re-auth for no reason.
Any ideas as to what I am doing wrong?
Thanks!
Here is the JS set up on my site:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: 'XXXXX',
channelUrl: 'http://www.domain.com/channel.php',
status: true,
cookie: true,
xfbml: true,
oauth: true,
});
FB.Event.subscribe('auth.login', function(response) {
alert('refreshing')
window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
window.location.reload();
});
FB.Canvas.setSize({ width: 810 });
FB.Canvas.setAutoGrow();
};
(function(d, debug){
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" + (debug ? "/debug" : "") + ".js";
ref.parentNode.insertBefore(js, ref);
}(document, /*debug*/ true));
</script>
Here is the PHP flow of calling the Facebook Object
$fb = new FbDoa();
if ($fb->isAuthed() === false) {
echo $fb->getLoginButton();
}
else {
echo $fb->getProfileInfo();
}
Here is the PHP contents of the FbDoa Object ($fb):
public function __construct() {
require_once(Facebook/facebook.php');
$this->facebook = new Facebook(array(
'appId' => 'XXXXX',
'secret' => 'XXXXXXXXXX',
'cookie' => true,
));
$this->user = $this->facebook->getUser();
if ($this->user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$this->user_profile = $this->facebook->api('/me');
} catch (FacebookApiException $e) {
//echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$this->user = null;
}
}
}
public function isAuthed() {
if ($this->user) {
return true;
}
else {
return false;
}
}
public function getLoginButton() {
$scope = 'email,user_likes,friends_likes,publish_actions,publish_stream,read_friendlists';
return '<fb:login-button size="xlarge" perms="'.$scope.'"></fb:login-button>';
}
public function getProfileInfo() {
return $this->user_profile;
}
UPDATE 1:
It really seems like window.location.reload(); is not doing anything, if I hit the login button over and over nothing happens, but I refresh it works. That being true the app's auth should last longer than a couple mins, which means there are a few issues before me. Any ideas?
UPDATE 2:
The issue could be with my server-side code? anyone know anything about PHP+JS SDK?
The signed request is saved in a cookie similar to fbsr_appid. From that you can use the code to deal with it. Here is how your flow should look
As long as there is a base url in your app settings it should redirect to all.

Facebook JS SDK does not set cookie

I'm trying to implement Facebook authentication in our web app, with server side processing of the Facebook cookie. We use the JavaScript SDK to perform our login and set the cookie.
Somehow, however, the Facebook SDK does not appear to set our fbsr_APPID cookie (or any cookie whatsoever). This is the CoffeeScript code:
window.fbCallbacks = []
# Create initialization function
window.fbAsyncInit = ->
fbConfig =
appId: '<APPID here>'
channelUrl: '/assets/channel.html'
status: true
cookie: true
xfbml: true
FB.init fbConfig
cb() for cb in window.fbCallbacks
# Set it up
((d)->
id = 'facebook-jssdk'
ref = d.getElementsByTagName('script')[0]
return if d.getElementById id
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)
We let Facebook perform the login via the provided login widget:
<div class="fb-login-button" data-show-faces="true" data-scope="publish_stream"/>
Some extra information:
This was tested in Chrome stable and canary as well as IE9, both on localhost and 127.0.0.1, with and without the --enable-file-cookies set (for what it's worth). I'd say that means it's not a browser issue.
I've tried fiddling with the channel file, but it seems perfectly accessible where it is now.
Setting a cookie in my own code from JS works like it should.
The JS SDK loads fine, because my login widget is properly decorated, and even shows that I've logged in already after I did.
No errors are reported in the console. It's completely blank.
Replacing the CoffeeScript with a copy from the initialization code JavaScript example on the Facebook Developers does not make it work either.
So what's happening? Why isn't Facebook setting my app cookie?
For reference, here is the JavaScript generated by the CoffeeScript above:
(function() {
window.fbCallbacks = [];
window.fbAsyncInit = function() {
var cb, fbConfig, _i, _len, _ref, _results;
fbConfig = {
appId: '<appid>',
channelUrl: '/assets/channel.html',
status: true,
cookie: true,
xfbml: true
};
FB.init(fbConfig);
_ref = window.fbCallbacks;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
_results.push(cb());
}
return _results;
};
(function(d) {
var id, js, ref;
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";
return ref.parentNode.insertBefore(js, ref);
})(document);
}).call(this);
It appears I misunderstood the SDK. The login button widget does not actually set a cookie locally; it manages authentication and access through Facebook and JavaScript entirely and therefore does not allow you access to an authentication token on the server.
Using the JS SDK's FB.login() function did set the cookie.

How to get page events from Facebook?

I'm using this code, but it returns empty data array. My access_token has all permissions. I know PAGE_ID, now i need to get events from this page.Thanks
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : APP_ID, // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// 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));
var interval = setInterval(function() {
if (typeof FB != 'undefined') {
clearInterval(interval);
FB.api('/' + PAGE_ID +'/events?access_token=' + ACCESS_TOKEN, function(response) {
//do something with response
});
}
}, 20);
</script>
It's not clear from your code how you are obtaining the access_token - are you using the access token for the page\account for which you need to retrieve the events? The way I have been doing it (not sure where I picked up this technique) for page events is to loop through the user accounts to get the access token for the page in question. Something like this (php)
$accounts = $facebook->api('/me/accounts');
foreach($accounts['data'] as $account){
if($account['id'] == $page_id){
$page_access_token = $account['access_token'];
}
}
My first access_token for my APP which i get from http://developers.facebook.com/tools/explorer/ was wrong. (Maybe it's only for test mode) Because i couldn't get events by this access_token.
On http://developers.facebook.com/docs/authentication/applications/ was written:
App Access Tokens generally do not expire. Once generated, they are valid indefinitely.
To obtain an App Access Token, perform an HTTP GET on:
https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials
I got access_token using HTTP GET, by this access_token i get events from facebook page: https://graph.facebook.com/PAGE_ID/events