NOTE: This is a facebook app which runs at page tab.
i have data.php file which gets all thing.
i get signed request with this following code:
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => false
));
$access_token = $facebook->getAccessToken();
$signedRequest = $facebook->getSignedRequest();
$user_id = $signedRequest['user_id'];
$liked = $signedRequest['page']['liked'];
In my index file i have some include action for fan or not fan and step php files.
Here is my index code:
require_once ('data.php');
if(isset($fid)){
if(isset($liked)){
$step = CHECK_STEP($fid);
if(isset($step)){
if($step == '1'){
include('fan-step1.php');
}
if($step == '2'){
include('fan-step2.php');
}
if($step == '3'){
include('fan-step3.php');
}
if($step == '4'){
include('fan-step4.php');
}
} else {
include('fan.php');
}
} else {
include('notfan.php');
}
} else {
if(isset($liked)){
include('fan.php');
} else {
include('notfan.php');
}
}
i'm using ajax in step php files to update database for step check. if ajax action complete, action reflesh the page. Code:
success: function(){
window.location = window.location.pathname;
}
after refreshing the page index file or data file cant get the page liked request. then if i refresh the page manual (ctrl+F5). It get the request and include next step php file.
What is wrong? why it cant get the liked request after js refresh?
With your redirection, you refresh your iframe. The signed request of facebook however, is sent via POST to your iframe. So if you just refresh your iframe, the signed request will not be sent again, since the second request (after the refresh), the request is not performed by facebook, but from within your application.
Reload the complete page (facebook + your tab) instead, using top.location.
Related
I'm working with Slim Framework and I would like to redirect the user to the login page if the user has lost his session but I'm always getting a SyntaxError : Unexpected token < at position 0.
My session validation code in php is this:
private function _validaSessao() {
$user = $this->userData['IdUser'];
if(null === $user || trim($user) == '') {
header("Location: http://192.168.0.9/", true, 301);
die();
}
}
I've tried that and all the following:
header('refresh:5;url=http://192.168.0.9/');
echo '<script>window.location.href = "http://192.168.0.9/";</script>';
return('<script>window.location.href = "http://192.168.0.9/";</script>');
echo json_encode('<meta HTTP-EQUIV="REFRESH" content="0; url=http://192.168.0.9/">');
I've tried them all and I'm always getting
200 ---- SyntaxError: Unexpected token < in JSON at position 0
The only piece of code that worked for me was:
echo json_encode(array(
'SemSessao' => true
));
But the above code makes me checking on every single call on JavaScript and I would like a solution that PHP will redirect me. This way I wouldn't need to keep checking on every single JS call (which are a lot) and each time a php object was instanciated it would check for session and redirect the user without the use of JS.
Update 1 - Include JS code (lovely downvotes everywhere :D)
getDadosPlaneamento: function() {
var req = {Rota: '/planeamento/getDados/AUTO'};
var dfd = $.Deferred();
$.when(App.gajax(req)).done(function(d) {
On.Planeamentos = d.Planeamentos;
dfd.resolve();
});
return dfd.promise();
},
The above code is what refers to my php route and then:
$onapp->get('/planeamento/getDados/:tipo/', function($tipo) {
if ($tipo == 'AUTO') {
$P = new MongoApi\Planeamento();
$ret = array(
$P->getAllMongo();
);
}
echo json_encode($ret);
});
And when I do $P = new MongoApi\Planeamento(); I check if the user has a valid session on the constructor using _validaSessao();
The server cannot redirect a client from an AJAX call. The AJAX call is a background HTTP request. Whether that HTTP requests gets redirected or not is irrelevant to the browser. The browser will return the request response to the AJAX client, and if that response is "your request has been redirected" then that's that. Again, a redirect doesn't redirect "the browser", it redirects the HTTP request. Or more precisely speaking, it tells the HTTP client that it should retry its request somewhere else; nothing more.
If your AJAX requests can fail due to a session timeout and whenever that happens you want to present the user with a login page, you will have to do that client side. In order to not repeat that same code every time, you make a function/object/service out of that. E.g. something along the lines of:
function makeAJAXRequest(url, data) {
return fetch(url)
.then(response => {
if (response.status == 403) {
window.location = '/login';
throw new Error('Forbidden');
} else {
return response;
}
});
}
Here the server is expected to respond with a 403 Forbidden status code for unauthorised requests. If you make all your AJAX requests through this function, it will automatically handle that case by redirecting to the login page.
Remeber that header() must be called before any output is generated. you can use ob_start() and op_end_flush() to avoid output previous to your header.
ob_start ();
header ("Location: http://192.168.0.9/", true, 301);
ob_end_flush ();
Problem
I am using below mentioned JS code in my PHP try catch. Basically I am making facebook app. In that when users session gets timed out it shows an error message which doesn't look good but when a user refreshes the page it starts working perfectly. For that reason I used PHP try catch to know whether the session got timed out or not if yes then in catch I run the below JavaScript code. I want to auto refresh the page instead of asking user to do it manually.
The below code refreshes the page but then it keeps refreshing it. I'm new to javascript can you please suggest how should I get out of this condition once it gets true.
Code
try{
$facebook = new Facebook(array(
'appId' => '123456789',
'secret' => 'some_secret',
));
$accessToken = $facebook->getAccessToken();
$facebook->setAccessToken($accessToken);
$user_profile = $facebook->api('/me','GET');
$username= $user_profile['email'];
$fb_id= $user_profile['id'];
}catch(Exception $e){
location.reload(true);
console.log('Session has been timed out');
}
<script type="text/javascript">
if(window.location.hash==-1)
{
//add a # if it doesn't exist
newurl = document.URL+"#";
location = "#";
//Refresh page
location.reload(true);
}
</script>
or try this(will not work if the user has disabled local storage/cookies)
function()
{
if( window.localStorage )
{
if( !localStorage.getItem( 'firstLoad' ) )
{
localStorage[ 'firstLoad' ] = true;
location.reload(true);
}
else
localStorage.removeItem( 'firstLoad' );
}
}
Possible duplicate of facebook Uncaught OAuthException: An active access token must be used to query information about the current user
But I did not get a proper solution.
I am using facebook sdk with codeigniter it is working properly. but sometimes it throws exception OAuthException: An active access token must be used to query information about the current user.
Here is the code of Controller file
$config = array(
'appId' => 'XXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
'fileUpload' => true,
);
$this->load->library('facebook/Facebook', $config);
$fbme = null;
$user = $this->facebook->getUser();
if ($user) {
try {
$fbme = $this->facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
//if user is logged in and session is valid.
if ($fbme){
//do some stuff...
//redirecting to user home page (my site's)
}
In view file, I am using js sdk. Code for view file is
<div id="fb-root"></div>
<script type="text/javascript">
var button2;
window.fbAsyncInit = function() {
FB.init({ appId: 'XXXXXXXX',
status: true,
cookie: true,
xfbml: true,
oauth: true});
function updateButton(response) {
button1 = document.getElementById('fb-login'); //login button
button2 = document.getElementById('fb-logout'); //logout button
if (response.authResponse) {
//user is already logged in and connected
button2.onclick = function() {
FB.logout(function(response) {});
};
} else {
//user is not connected to your app or logged out
button1.onclick = function() {
FB.login(function(response) {
if (response.authResponse) {
} else {
//user cancelled login or did not grant authorization
}
}, {scope:'email,user_birthday,user_about_me,user_likes,user_interests,user_education_history,user_work_history'});
}
}
}
// run once with current status and whenever the status changes
FB.getLoginStatus(updateButton);
FB.Event.subscribe('auth.login', function(response) {
window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
window.location.reload();
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol
+ '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
PROBLEM:
Sometimes the it throws "OAuthException: An active access token must be used to query information about the current user." to the error log file.
Case: user is logged in facebook and has already authenticated my app
If a user is logged in facebook and authenticated my app and tries to logged in to my site,
rather redirecting the user to my site (php sdk is not working in this case), it is loading the view file. In view file also I am checking whether the user is logged in in facebook or not. (in view) if the user is logged in it will reload the page, same controller script will run and it redirects the user to user's home page(php sdk is working in this case.).
But first time it is not working. Don't know where I am making the mistake.
Also that logout button (in view file) is also sometimes not working. Means on clicking it is not logging out the user from facebook. (It is only happening in one of my colleague's browser. She is using chrome in windows 7)
I was having a similar problem while using PHP-SDK + JS-SDK together. I temporarily solved it by removing the FB.init "cookie:true" option.
By some reason that I couldn't find, an invalid signedRequest cookie is being shared between PHP and JS, then, the valid access_token of the PHP Session was being override with an invalid access_token, thus, destroying the previously valid PHP token.
The difference between my problem and yours is that you're logging via JS and trying to access the same session on PHP (I was doing it backwards, logging on PHP and trying to use the JS-SDK).
This bug is apparently fixed on this pull request:
https://github.com/facebook/facebook-php-sdk/pull/48
I'm using twitteroauth.php to add login functionality to my website using twitter api.
It works fine. But i want to implement the same using jQuery and AJAX so that page won't get refreshed on return.
Following is my piece of code
<?php
require("twitter/twitteroauth.php");
require 'config/twconfig.php';
session_start();
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET);
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$request_token = $twitteroauth->getRequestToken('http://list.2lessons.com/fbtwLogin/getTwitterData.php');
// Saving them into the session
$_SESSION['oauth_token'] = $request_token['oauth_token'];
$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
// If everything goes well..
if ($twitteroauth->http_code == 200) {
// Let's generate the URL and redirect
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
header('Location: ' . $url);
} else {
// It's a bad idea to kill the script, but we've got to know when there's an error.
die('Something wrong happened.');
}
?>
I was searching for something similar to Facebook JS SDK for Twitter login. Facebook JS SDK does not refresh the page when logging in. I have made my own using JS Popup window. It's actually not using AJAX.
a. You need a link to trigger popup window:
< a href="#" onclick="window.open('http://localhost.com/twitter_login.php', 'Twitter', 'width=640,height=480');">Login to Twitter< /a>
b. PHP script for Twitter login (The code you've submitted above) and
callback (Where user lands after login).
Callback should look like:
<?php
// In php part you should store information about login (AccessToken, User info, and anything else you want) into DB
?>
<html>
<head><title></title></head>
<body>
<!-- In html part I let user know that he/she has been logged in. In my case, Twitter icons -->
<script type="text/javascript">
if(window.opener && !window.opener.closed) {
window.opener.refreshTwitterIcons(); // function is called in parent window from which user has triggered the popup
}
window.close(); // Closing the popup
</script>
</body>
</html>
It's quite easy by using jQuery's $.ajax() function, where you basically post your data to your PHP code.
The only thing that needs a change is the header section - you might want to return a JSON encoded message - like "OK" or "Error Message", so you can react upon that.
$.ajax({
url: "your_file.php",
type: 'post',
dataType: 'json',
success: function(data, status, xhr) {
if (data.msg == 'OK') {
// all ok, user logged in
} else {
// display error
console.log(data.msg);
}
}
});
And the PHP part:
<?php
require("twitter/twitteroauth.php");
require 'config/twconfig.php';
session_start();
$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET);
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$request_token = $twitteroauth->getRequestToken('http://list.2lessons.com/fbtwLogin/getTwitterData.php');
// Saving them into the session
$_SESSION['oauth_token'] = $request_token['oauth_token'];
$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
// If everything goes well..
if ($twitteroauth->http_code == 200) {
// Let's generate the URL and redirect
$url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
echo json_encod(array('msg' => 'OK'));
} else {
// It's a bad idea to kill the script, but we've got to know when there's an error.
echo json_encod(array('msg' => 'Something wrong happened.'));
}
?>
I've set up a Canvas Page which doe's a FB.login on click of a form submit button. During the following request it tries to access the users data via $facebook->api('/me') (last API version from Github). It works in Firefox and Chrome, but not in Safari and IE, where the API fails with "auth token required". Has anybody already had this problem or got an idea what could cause it?
BR Philipp
edit:
I call FB.login inside the click event of a form submit button:
$('.form-submit', this).click(function() {
FB.getLoginStatus(function(response) {
if (response.session) {
form.submit();
} else {
FB.login(function(response) {
if(response.session && (permissions == '' || response.perms)) {
form.submit();
}
else {
}
},{perms:permissions});
}
});
return false;
});
On server side in simply construct the php-api object and try to get user data:
$facebook = new Facebook(array(
'appId' => $appid,
'secret' => $appsecret,
'cookie' => TRUE,
));
if ($facebook) {
try {
$me = $api->api('/me');
}
catch (Exception $exc) {
// Failure in Safari and IE due to invalid auth token
}
}
The signed_request is passed inside a hidden form element.
I had the same problem and I've included a solution below.
I believe the reason this happens is because on a Javascript login attempt your server never receives any access tokens. The Javascript is only passing data between your browser and Facebook.com so your server has no idea what the authentication status is. Your server will only receive the new access tokens when the page is refreshed; this is where facebook hands over the access tokens.
Heres my solution.
Upon a successful login via FB.login you will receive the response object and inside it is an access_token. All you need to do is pass this access token to your script in some way. Here is an example:
// Hold the access token
var js_access_token = "";
// Connect to facebook
FB.login(function(response) {
if (response.session) {
if (response.perms) {
// user is logged in and granted some permissions.
// Save the access token
js_access_token = response.session.access_token;
// Do stuff on login
}
}
});
You then include the access token along with any requests. I've chosen an ajax example.
// Communication back to server.
$.ajax({
url: 'myurl.php',
data: {
js_access_token: js_access_token // Including the js_access_token
},
success: function(data) {
console.log(data);
}
});
Within your PHP you then need to have something which looks like this:
$facebook = new Facebook(array(
'appId' => $appid,
'secret' => $appsecret,
'cookie' => TRUE,
));
if ($facebook) {
// If we get the access token from javascript use it instead
if (isset($_REQUEST['js_access_token']) && $_REQUEST['js_access_token']) {
$facebook->setAccessToken($_REQUEST['js_access_token']);
}
try {
$me = $api->api('/me');
}
catch (Exception $exc) {
// Failure in Safari and IE due to invalid auth token
}
}
Hope this helps
I had a lot of troubles with the JS FB login stuff. I recommend using the simpler redirect login using oauth and the getLoginUrl function from php fb api.
So basically you do it from PHP, you check if you have your session, if not you use getLoginUrl and redirect to that page, your use will be then redirected to your app/site with a valid session (if he accepts).
Does this help ? I really lost HOURS trying to make the FB JS login work on any browser and I couldn't, I've switched since then to the simple redirect login method in all of my apps with complete success.
I liked Conor's answer as I had to pass my access token from the client side to server side as it was not working in Safari (cookie issues I presume). But this is an old question so a few things had to change. The vars are different now and as oliland pointed out we shouldn't be sending access tokens as GET params.
Anyway, here's what I ended up with in case it helps anyone
<a id="start-button" href="#">Start</a>
<form id="entry-form" action="nextpageurl" method="post">
<input type="hidden" name="access_token" />
</form>
<script>
$(document).ready(function() {
$('#start-button').click(function(e) {
e.preventDefault();
FB.login(function (response) {
if (response.authResponse) {
$('#entry-form input').val(response.authResponse.accessToken);
$('#entry-form').submit();
} else {
alert('Permissions required');
}
}, {});
});
});
</script>
and then in the PHP, pretty much same as Conor's answer, but getting the token from the $_POST var.