Retrieving appdata from facebook application - facebook-php-sdk

After almost 2 hours of try I'm posting this here,
I'm trying to retrieve list of parameters passed to my facebook application. Here is my application, https://apps.facebook.com/takeflights/index.php
When I'm loading the app with this URL https://apps.facebook.com/takeflights/index.php?id=5, $signed_request['app_data'] is not returning anything,
below is part of my code:
$facebook = new Facebook(array(
'appId' => 'xxxxxxxxxxxx',
'secret' => 'xxxxxxxxxx',
));
$signed_request = $facebook->getSignedRequest();
print_r($signed_request['app_data']);
I'm also searching for "allow signed_request" in application setting but not finding it

Your query is only printing the app_data part of the signed request. This has to be manually populated by your app via a query string.
To do it, your query should look something like this:
https://apps.facebook.com/takeflights/index.php?appdata=id%3D5%26page%3D1

Related

How to let a user choose different Facebook permissions in the same page?

Suppose you want to build a webpage with Facebook PHP SDK, where you want to allow the user to select the information Facebook will return to the server. I've came with the following code to allow an user to either choose from allowing Facebook to send only the basic profile or else to also send the pages managed by this user.
session_start();
// Load the Facebook PHP SDK
require_once __DIR__ . '/facebook-sdk-v5/autoload.php';
define('APP_ID', 'xxxxxxxxxxx');
define('APP_SECRET', 'xxxxxxxxxxxxxxxxxxxx');
$fbProfile = new Facebook\Facebook([
'app_id' => APP_ID,
'app_secret' => APP_SECRET,
'default_graph_version' => 'v2.7'
]);
$fbPages = new Facebook\Facebook([
'app_id' => APP_ID,
'app_secret' => APP_SECRET,
'default_graph_version' => 'v2.7'
]);
$helperProfile = $fbProfile->getRedirectLoginHelper();
$redirectUrlProfile = 'http://www.example.com/link1.php';
$loginUrlProfile = $helperProfile->getLoginUrl($redirectUrlProfile);
echo 'Get profile with Facebook!<br>';
$helperPages = $fbPages->getRedirectLoginHelper();
$permissions = ['pages_show_list']; // Optional permissions
$redirectUrlPages = "http://www.example.com/link2.php";
$loginUrlPages = $helperPages->getLoginUrl($redirectUrlPages, $permissions);
echo 'Get pages with Facebook!';
If I use the above code (commenting the non-relevant parts) with only one facebook object to either retrieve the profile or the pages managed by user (but not both), everything works fine. But if I use both objects concurrently to give a choice to the user, I get a FacebookSDKException. I guess this is due to CRSF cookies.
Is there any way to circunvent this problem?
I guess this is due to CRSF cookies.
Correct. Calling the getLoginUrl method creates a new random state value and writes it into the session, overwriting any previously stored one.
So if you call the method twice (or more times), login will only work if you call the login dialog via the last login URL created, because only that contains a state value that matches the one stored in the session.
If you want to keep using two different redirect URIs, then you need to implement an additional step to create the correct login URL, and only that one.
So you have two links in your page, both pointing to a script on your server, and passing what permissions to ask for via a GET parameter (whether you want to pass permission names directly, or just a flag like ?loginmode=1/?loginmode=2, is up to you.)
In that script, you decide which redirect URI and scope value to call the getLoginUrl method with - once. And then your script just redirects to that login URL.
(But keep in mind that the step that exchanges the code for an access token also requires the redirect URI parameter to be passed, again - and again with the exact same value that was used in the login dialog call.)
So doing it the way #luschn suggested in comments, using the JS SDK for login purposes, is probably much easier. FB.login can be called with different scopes from different points in your client-side JS code without any such problems.

How to get Iron-router query parameters in server hook

I am trying to add a referral system to my project, so currently I am basing it off of this package. The issue I am running into is my project only uses accounts-google and not accounts-password. The way this package works is it adds the iron router query parameters for the referrerCode (/register?r=ReferralCodeHere)through a preSignUpHook. I believe this only works with accounts-password wont work when creating an account with an API such as accounts-google.
My idea around this is to use a Meteor.users.before.insert hook to grab the iron router query parameters and insert them into my referrerCode field in Meteor.users since I'm already using Meteor Collection Hooks for a couple of other things.
The issue is I havent been able to find a way to get the query parameters on the server, I was hoping to do something like this:
Meteor.users.before.insert(function(userId, doc) {
doc.referrerCode = Referrer._referrerCode; // Link 1
});
(Link 1)
But this will just come up as undefined.
If I'm at my register page and it has a query like this for example: example.com/register?r=12345 Then I run Router.current().params.query.r on the client it returns 12345. Basically I just need to have that saved to the referralCode field in Meteor.users when a new user creates an account, if a referral code exists in the register URL.
I'm a bit lost with this one. I thought about setting it as a Session variable and then getting that in the before.insert hook, but that again only works on the client side. I'm thinking a meteor method might be best for this, but I'm not exactly sure how I would structure it. Any help is greatly appreciated!
Put the referral token into profile
Use that in your hook
Below I've copied some code that I've used before. It is built around an Invitations collection that tracks who invited who:
client:
var profile = {};
... any other profile settings you've captured
if ( token ) profile.referralToken = token;
Accounts.createUser({ email: email, password: password, profile: profile }, function(err){ ...})
hook:
if ( options.profile.referralToken ){ // referral case
var invitation = Invitations.findOne({ token: options.profile.referralToken });
if ( invitation )
user.invitationId = invitation._id; // the invitation used
user.invitedBy = invitation.userId; // the referring user
}
delete options.profile.referralToken;
}
return user;

What's the best practice/ a secure way for saving and processing a password of a plugin's option page?

First of all, I'm not a security expert and new to form validation, password storing and wp plugin development. Any wp plugin tutorial I've been looking at never had a chapter about API passwords. Googling for wordpress password issues didn't return any satisfying results. So that's why I'm asking here.
I want to create a custom Wordpress Plugin which works with a Soap API of another page. To use the Soap API a login is needed. So the Wordpress built in functions add_option(), update_option() and get_option() are all working with plain text.
But I know that in the wp_config file authentication keys can be saved. But how to use them in an option page form to encrypt the password? And would it be possible just to store them in the database, decrypt it and use it in the backend but not showing it on the options page if the user visits that page again. So that the password field just has some black spots in it (not the same amount of the chars of the pass) and the password option only is updated if something is written into that field.
Normally the code is like this:
register_setting( 'my_plugins_option', 'my_options', 'my_validation_function' );
$options = array(
'user' = > 'name',
'password' = > 'pass',
//... other options
)
update_option( 'my_plugins_option', $options );
But how could I make this more secure? I've seen many plugin examples but nothing was about storing passwords. I'm looking for something like this:
function my_validation_function($input){
if($input['password']=='•••••'){
//use the default value of the database if nothing was changed
$old_options=get_option('my_plugins_option');
$input['password']=some_decrypting_function($old_options['password']);
}
else{
//use the password sent from the form
$password=esc_sql(some_encrypting_function($input['password']));
}
// ... validate the other inputs
update_option( 'my_plugins_soap_api_pass', $password );
}
P.S.: This code is not tested yet of course because I don't know how to work with passwords in wordpress plugins and so I wanted to ask for the best practices first.
The other question is: If the modified version of the code from above would work and the password is saved once and never loaded into the Dashboard frontend again (just showing this: '•••••' once typed in) would it be save to work with the get_option() function, decrypt the password and use it in the backend?
Here are a couple recommendations. They aren't specific to WP, but can apply.
1) Save an encrypted password in the options table (use whatever encrypting function you want, just don't write your own)
2) In the options page, simply do NOT output the password. Leave that field blank, and don't require it to be entered if there is already a password stored in the database.
3) Only decrypt the password retrieved from the options table just prior to actually needing it in code.

"An active access token must be used" (Dec 2012) && The proper way to set up Facebooks PHP-SDK for Ajax calls to get the user-id

This is giving me quite some headache. I have an page-tab-application, where DB-interaction uses the facebook-user-id to assign and save data and also to check user permissions. Until a weak ago everything was working fine, but now with the upcoming december-changes this setup doesnt work anymore:
config.php:
$facebook = new Facebook( array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
index.php:
includes config.php and gets the signed request (not important for the question
javascript.js:
calls the read-user-status.php and handles the data
read-user-status.php:
gives json-response, includes config.php and calls the $facebook -> getUser()-function to get the uid
Even when called from the index.php directly after page-load, I sometimes get the uid and sometimes I don't. Strangly enough I usually have to wait a little until I reload the page and then it works again. But this isn't always the case. This all is just very strange to me.
EDIT: Should have mentioned that this call:
$uid = $facebook -> getUser();
if ($uid) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook -> api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$uid = FALSE;
echo "EXCEPTION $e";
}
}
gives out "EXCEPTION An active access token must be used to query information about the current user".
I know there quite a lot of similar questions out there, but none of the answers were helpful to my particular (and probably to the new breaking changes relied) problem.
EDIT2: I now suppose that it is a sdk-bug (https://developers.facebook.com/bugs/238039849657148 , thanks to CBroe). Any recommendations for a work-around are of course very welcome.
EDIT 3, TEMPORARY SOLUTION
Everytime you make an ajax request, you post the token you get from the FB.getLoginStatus or FB.login and read it out in the php file and set it via $facebook -> setAccessToken. Not suitable in all circumstances (you definately need to use post), is slower and brings some security issues, but still works.
Sounds like you are affected by the bug I reported beginning of November, https://developers.facebook.com/bugs/238039849657148
They’ve confirmed it and say they’re working on a fix – but since the change is only a few days away now, they should hurry up a little …
I got this working by doing the following...
if(!$user){
$loginUrl = $facebook->getLoginUrl(array(
'scope' => 'email',
'redirect_uri' => $app_url
));
header('Location: ' . $loginUrl);
}
I also added my app to be integrated with:
Website with Facebook login
App on Facebook
Page Tab
try by adding access token to request.
$accessToken = $facebook->getAccessToken();
$user_profile = $facebook->api('/me?access_token=' . $accessToken);
I found a work-around for this, until it is fixed (which it seems like, wont be in time until the changes take place).
Everytime you make an ajax request, you post the token you get from the FB.getLoginStatus or FB.login and read it out in the php file and set it via $facebook -> setAccessToken. Not suitable in all circumstances (you definately need to use post), is slower and brings some security issues, but still works.
if it you are lucky and your version of php sdk still registers session variables than right after _graph method declaration:
//find this method below
protected function _graph ($path, $method = 'GET', $params = array ())
{
//paste right after _graph method declaration code below:
if (isset($_SESSION["fb_".$this->getAppId()."_access_token"]))
{
$this->setAccessToken($_SESSION["fb_".$this->getAppId()."_access_token"]);
}
//till here
//and you are good to go
//remember: your version of sdk must be registering access token variable in session
//right after ajax call
//i used git to get version before last commit of sdk published on github

Custom usermeta fields, registration page and login widget wordpress

Here's the situation:
I have an old site, with an old userdatabase (MySQL). I'd like to migrate these users into wordpress without losing the old data (recipe id's, custom user fields etc.).
Besides this i'd like to make a custom registration page with all the (extra) user data i allready had on the old site.
I tried to find some plugins (WP-members, Registration Widget, Register Plus Redux, etc.), but they all didn't fit my purpose.
I'm starting to think that I probably need to code this myself, but that will make Wordpress unable to update.
Does anyone have a solution for this problem?
Thx, Rick
Should be fairly easy although you may have to assign users a new password. That is usually ok with the users as long as they know it's coming.
Take your old database and to a simple sql query to extract the data, then use some code like the following to create a new user for each user in your old database:
$newuser = array(
'user_pass' => wp_generate_password( 12,0 ),
'user_login' => $email,
'user_nicename' => $name['first'].' '.$name['last'],
'user_email' => $email,
'display_name' => $name['first'].' '.$name['last'],
'nickname' => $name['first'].' '.$name['last'],
'first_name' => $name['first'],
'last_name' => $name['last'],
//''
);
$user_id = wp_insert_user($newuser);
wp_new_user_notification($user_id, $newuser['user_pass']);
This code works as of WordPress 3.1. In this example you'd simply want to replace the $name variables with data that you've provided from your old database.
The last two lines are important because that's where the real work happens. The wp_insert_user function will create the user (or throw an error if you're missing info) and the wp_new_user_notification function will send them an email with their password. I would highly recommend taking the time to rewrite the new user notification plugin (it's a pluggable function so you can just copy paste it to your functions.php and make changes there) so that the email users get makes sense. You could also write your own email function or if your passwords are stored in plain text simply pass that info on to WP.
Edit: I missed your need for custom fields, Gravity Forms does this quite well but you can add a custom field to any user with the update_user_meta function. So in the sample code above you'd just want add something after that like:
update_user_meta($user_id, "my_custom_data_key", "my_custom_data_value");
To retrieve that data for display, you'd just use get_user_meta:
print get_user_meta($user_id, "my_custom_data_key");

Resources