I have problems with authorizing of the user in a facebook page tab. I have tried a lot of different methods in both PHP and Javascript without any luck at all basically.
If someone could explain this for me and show some code it would be great! I was thinking on to do the authorizing in PHP and then continue to grab some user-data width Javascript.
I also need to be able to let the user agree on the persmissions. so a popup for authorizing and permissions is what i need help with.
What do you think? Is there a better way?
Help with some code for this would as i said be great!
In order to know whether user already authenticated your app or not, decode signed_request and check if oauth_token is passed:
<?php
$secret='APP_SECRET';
$signed_request=($_REQUEST['signed_request']);
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;}
// check signature
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
$information=parse_signed_request($signed_request, $secret);
$oauth_token=$information["oauth_token"];
?>
Then, use this script to get user authenticated if $oauth_token is empty:
<?php
$app_id = "APP_ID";
$canvas_page = "YOUR_TAB_URL";
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page) . "&scope=ENTER WANTED PERMISSIONS HERE";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($oauth_token)) {echo("<script> top.location.href='" . $auth_url . "'</script>");}
?>
Fill in APP_SECRET, APP_ID, YOUR_TAB_URL and WANTED PERMISSIONS in these scripts, cheers.
Related
I have a little Facebook app, which has a "like gate" at the beginning. The user have to like the page to use the app. The app itself has some subpages, so I have to store the signed request into $_SESSION variable if I want the subpages to work. My problem is that the signed request is only sent on app load and at this time the user hasn't liked the page yet. So if this time the signed request is saved, the $signed_request["page"]["liked"] will alway return FALSE... How can I reload the signed request?
FQL and $like_data = $facebook->api('/me/likes/PAGE-ID/'); isn't good, because I want the permission dialog AFTER the page like.
This is the code right now:
$page_id = $signed_request["page"]["id"];
$like_status = $signed_request["page"]["liked"];
if(!$like_status){
header("Location: notfan.php");
exit;
}else{
if (!isset($_SESSION["SR"]))
{
$_SESSION["SR"] = $_REQUEST["signed_request"];
}else{
$encoded_sig = null;
$payload = null;
list($encoded_sig, $payload) = explode('.', $_SESSION["SR"], 2);
$sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
$signed_request = $data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
$signed_request = objectToArray($signed_request);
}
}
Thank you very much!
just save the signed request every time you encounter it in the request: When the user likes the page, Facebook will do a page reload and resends the signed request
edit:
You're setting $like_status and checking it before you even know if you have a signed request and before you set the value of $like_status.
I would check the request parameter first, the session second, then fill the $like_status variable, then check the $like_status.
Something like this:
if( isset($_POST['signed_request']) )
{
$_SESSION["SR"] = $_REQUEST["signed_request"];
}
if (!isset($_SESSION["SR"]))
{
//shouldn't even happen now when page is opened through facebook,
//so you might want some error handling here
}
$encoded_sig = null;
$payload = null;
list($encoded_sig, $payload) = explode('.', $_SESSION["SR"], 2);
$sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
$signed_request = $data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
$signed_request = objectToArray($signed_request);
$page_id = $signed_request["page"]["id"];
$like_status = $signed_request["page"]["liked"];
if(!$like_status){
header("Location: notfan.php");
exit;
}
I'm trying to allow users to register on my web application via Facebook. As part of my normal registration users must supply their email address, and I need to include this as part of the Facebook registration.
I am using the code below, which works correctly, except it doesnt return the user email address as part of Facebook's response. I am aware I need to specifically "ask" for the email, but I'm confused where/how I do this in my code below?
I am also aware a user may choose to not supply their email address as part of the process, but I'm able to handle that.
// Grab our facebook details
$app_id = $this->config->item('fb_app_id');
$app_secret = $this->config->item('fb_secret_key');
$my_url = $this->config->item('fb_url');
session_start();
if(isset($_REQUEST["code"]))
{
$code = $_REQUEST["code"];
}
else
{
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state'];
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if ((isset($_REQUEST['state'])) && (($_REQUEST['state'] == $_SESSION['state'])))
{
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/me?access_token=". $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
if ( ! empty($user))
{
// NO EMAIL HERE?!
$email = strtolower($user->email);
}
}
Looks like this has been asked before. The answer can be found here:
Facebook Graph API, how to get users email?
This code works for me...Hopefully it will work well for you also
define('FACEBOOK_APP_ID', 'YOUR_APP_ID_HERE');
define('FACEBOOK_SECRET', 'YOUR_APP_SECRET_HERE');
// No need to change function body
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
if ($_REQUEST) {
$response = parse_signed_request($_REQUEST['signed_request'],
FACEBOOK_SECRET);
/*
echo "<pre>";
print_r($response);
echo "</pre>"; // Uncomment this for printing the response Array
*/
$email = $response["registration"]["email"];
I'm trying to make it so my facebook app is available in English and Japanese.
I tried using tags but could not get them to work:
http://developers.facebook.com/docs/internationalization/
I then thought I'd just make two versions of the app, one in English, the other in Japanese. When I open my app, the oauth permission dialog is shown. I approve the app and then it takes me to a page which keeps looping, producing a new $_GET['code'] each time. I then click on "facebook" at the top left hand corner of the screen. I then click on my app again and this time I can access it ok in English or Japanese. How can I stop the app looping the first time around? How can I go directly to the version of the app based on the users locale? Thanks
<?php
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
$result = parse_signed_request($_REQUEST['signed_request'],"app_secret");
$locale = $result['user']['locale'];
$token = $result['oauth_token'];
if ($token != ""){
if ($locale == "ja_JP"){
if ($_SERVER['HTTPS']){
header("Location: https://secure.example.com/facebook/ja/index.php");
exit;
}
else {
header("Location: http://example.com/facebook/ja/index.php");
exit;
}
}
else{
if ($_SERVER['HTTPS']){
header("Location: https://secure.example.com/facebook/en/index.php");
exit;
}
else {
header("Location: http://example.com/facebook/en/index.php");
exit;
}
}
}
else {
if($_SERVER['HTTPS']){
$canvas_page = "https://secure.example.com/facebook/";
}
else {
$canvas_page = "http://example.com/facebook/";
}
$app_id = "my_app_id";
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page) . "&scope=email";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
echo("<script> top.location.href='" . $auth_url . "'</script>");
exit;
}
?>
You could put all your texts in a simple locale-based array. You first need to get the user's locale, then use it as a key
$loc["ja_JP"]["MyText"] = "My JP text";
$loc["en_US"]["MyText"] = "My US text";
$result = parse_signed_request($_REQUEST['signed_request'],"app_secret");
$locale = $result['user']['locale'];
echo $loc[$locale]["MyText"];
For resources (specific localized pictures for example), you could get the files in a locale-based directory.
how i can set a manage_pages permission of my application to a particular page only. Now my application get permission to manage all pages of fb user.. How i can restrict this and get permission to access a specific page only ?
I am using one simple authentication method.
$app_id = 'xxxxxxxxxxxxx';
$app_secret = 'xxxxxxxxxxxxxxxx';
$my_url = 'http://xxxxxxxxxxx.com/xxxx/facebook?client=params';
$code = $_REQUEST["code"];
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url).'&scope=offline_access,read_stream,publish_stream,manage_pages';
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$token_url = 'https://graph.facebook.com/oauth/access_token?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url)
. '&client_secret=' . $app_secret
. '&code=' . $code;
$access_token = file_get_contents($token_url);
am using the above code for authentication. when i try to print the $_REQUEST params, i couldnt find any variable names 'signed_request'. is any other method can we use with the above code..??
Unfortunately that's not possible. Very annoying but well.. it's facebook so there's nothing else to expect.
You should do this from your side. Facebook will send you the page id in the signed_request so you can verify the page and show/disable content:
<?php
if(!empty($_REQUEST["signed_request"])) {
$app_secret = "APP_SECRET";
$data = parse_signed_request($_REQUEST["signed_request"], $app_secret);
if (isset($data["page"])) {
echo $data["page"]["id"];
} else {
echo "Not in a page";
}
}
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
This code is taken from this answer. Just check the $data["page"]["id"] against the one you want.
I wanted to know , will this tag of Static FBML would work in IFrame anyway :-
fb : userlink uid="loggedinuser"
And my Second question is , Can We get User ID Through Cokkies stored rather using FBML as on iframe facebook wont allow us to access Users DATA.
So Using Firebug I found we Get the Users Id. and is stored in cookie.
I want the user to be Restricted for More than one time Access to my Iframe . So by getting The User ID
I would like to check , whether the user had registered or not. and if he had Registered. He cant Register Twice .
I am trying it by Using Cokkies , But due to Lack of knowledge about JAVASCRIPT , I am not getting How to execute it.
Put the following code in your iframe and you will get the logged in user id then check constraint on it .
<?php
function parse_signed_request($signed_request , $secret ) {
$signed_request = $signed_request ? $signed_request : $_REQUEST['signed_request'];
$secret = $secret ? $secret : your_app_secret;
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
$request=$_REQUEST['signed_request'];
$appsecret = 'your_app_secret_key';
$new = parse_signed_request($request , $appsecret );
echo $new['user_id'];