Facebook SDK not public for visiters - javascript

I made an FB.api that get the last 2 posts of my facebook page. I added it to my personal website. It works on my website, but when someone else visit my website they can't see my last posts...When I googled the problem, I saw my FB app need to be live. So I did it. But it still doesn't work...
Here is my code:
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
});
};
function toonID() {
FB.api('/PAGE_ID/feed?limit=2', function (response) {
var str = "";
for (var i = 0; i < response.data.length; i++) {
//console.log(i + " : " + response.data[i].message);
//str += "<b>id: </b>" + response.data[i].id.slice(16) + "<br><br />";
str += "<div class='fb-post' data-href='https://www.facebook.com/Beatpounce/posts/" + response.data[i].id.slice(16) + "' data-width='466'></div><br /><br />";
}
document.getElementById("post").innerHTML = str;
});
}
I think I need an acces_token but I don't know how to use

You need to use at least an App Token for the call - but you should do that API call server side, because the App Token includes your App Secret and you should never reveal your App Secret on the client. User PHP cURL for that call and add your App Token as access_token parameter.
More information about Tokens:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/

Related

Plaid::InvalidRequestError

I am working on sending info from the Plaid link button using this tutorial from Stripe.
I have added the following code to the onSuccess function:
onSuccess: function(public_token, metadata) {
// Send the public_token and account ID to your app server.
var form = $('#payment-form');
form.append("<input type='hidden' name='plaid_public_token' value='" + public_token + "'/>");
form.append("<input type='hidden' name='plaid_account_id' value='" + metadata.account_id + "'/>");
form.get(0).submit();
}
I thought this function would be called when the user successfully adds their bank using the Plaid link. Essentially, this would get called when the form closes.
However, the behavior appears that it submits the form when the user opens the Plaid link, sending blank data to my controller.
How can I send this information to my server when Plaid is complete? Currently, it's saying that the variables are empty, but I think it's because I can't even use the Plaid pop-up before this error is being thrown.
Plaid::InvalidRequestError (
Error Type : INVALID_REQUEST
Error Code : INVALID_FIELD
Error Message : public_token must be a non-empty string
Display Message :
Request ID : A1AXs
):
in regards to "public_token must be a non-empty string" and the link given from stripe.
when you create Plaid and give it a config it seems like possibly you're not giving it your link token as shown in example. Start by creating an object that contains all the needed props ie: onSuccess, onExits and token
based on what you have and what is given should look like the following:
const configs = {
// where linkData.link_token is data returned from the call to the link api.
token: linkData.link_token || '',
onLoad: function() {
// The Link module finished loading.
},
onSuccess: function(public_token, metadata) {
// Send the public_token and account ID to your app server.
var form = $('#payment-form');
form.append("<input type='hidden' name='plaid_public_token' value='" + public_token + "'/>");
form.append("<input type='hidden' name='plaid_account_id' value='" + metadata.account_id + "'/>");
form.get(0).submit();
},
onExit: async function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error
// prior to exiting.
}
// metadata contains information about the institution
// that the user selected and the most recent
// API request IDs.
// Storing this information can be helpful for support.
},
};
var linkHandler = Plaid.create(configs);

Log in to Linkedin programmatically using javascript api

I have a personal blog and I want to populate the "about me" section with my Linkedin data.
What's the best way to programmatically login to Linkedin with my own credentials and serve up the data?
I don't want vistors having to login to linkedin to be able to see "MY" linkedin data.
Any idea on the best approach for this?
This is the start of my code, I'm just starting out and getting an understanding of the flow.
(function($, window) {
"use strict";
var Linkedin = {
Config: {
API_KEY: "API_KEY",
SECRET_KEY: "SECRET_KEY",
URL: "http://www.hanger-designs.co.uk:8888/wemustcreate/",
END_POINT: "http://platform.linkedin.com/in.js"
},
initalise: function() {
this.insertScript(this.returnedFunc, this.Config.END_POINT);
},
insertScript: function(callback, endPoint) {
var code = "api_key:" + this.Config.API_KEY + "\n" +
"onLoad:" + callback + "\n" +
"authorize: true"
var scriptElement = document.createElement('script');
scriptElement.text = code;
scriptElement.type = 'text/javascript';
scriptElement.src = this.Config.END_POINT;
document.body.appendChild(scriptElement);
},
returnedFunc: function() {
console.log('callback', arguments);
}
}
Linkedin.initalise();
})(jQuery, window);
To do this you need to authorize with OAuth. You blog can do this authorization (PHP/Perl/whatnot), but the clients cannot (JavaScript).
The reasons for this:
you are sharing the secret key, which can allow anyone access
you need to store state somewhere (the token). You should not store this on the client. You need a server in order to save the token.

Creating a post by sending HTTP request to Facebook API

I want to post on my facebook page by sending a HTTP POST. The way I am doing this is by creating a permanent access_token that is used to post to my facebook page. The problem is the access_token can be easily taken/inspected using firebug or any other tool (since it is hard-coded). How can I send it in a way that is kept from others.
$appID = 'MY_APP_ID';
$fb_page_id = 'MY_PAGE_ID';
$fb_page_access_token = 'PERMANENT_ACCESS_TOKEN';
$html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
. '<html><body>'
. '<div id="fb-root"></div>'
. "<script type=\"text/javascript\">
function post_to_fb(commentText, commentUsername, commentLink) {
var logoName = get_logoname_from_link(commentLink);
var strURL = 'https://graph.facebook.com/" . $fb_page_id . "/feed';
var params = 'link=' + commentLink + '&name=Brandchamp+-+' + logoName + '&message=[' + commentUsername +'+commented on ' + logoName + ':]+' + commentText + '&access_token=" . $fb_page_access_token . "';
var xmlHttpReq;
xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.open('POST', strURL, true);
xmlHttpReq.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlHttpReq.send(params);
}
window.fbAsyncInit = function() {
FB.init({
appId: " . $appID . ",
status: true,
cookie: true,
xfbml: true,
});
FB.Event.subscribe('comment.create', function(response) {
var commentQuery = FB.Data.query('SELECT fromid, text FROM comment WHERE post_fbid=\'' + response.commentID + '\' AND object_id IN (SELECT comments_fbid FROM link_stat WHERE url=\'' + response.href + '\')');
var userQuery = FB.Data.query('SELECT name FROM user WHERE uid in (select fromid from {0})', commentQuery);
FB.Data.waitOn([commentQuery, userQuery], function () {
var commentRow = commentQuery.value[0];
var userRow = userQuery.value[0];
var commentText = commentRow.text;
var commentUsername = userRow.name;
post_to_fb(commentText, commentUsername, response.href);
});
});
};
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/de_DE/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>"
. '</body></html>';
print $html;
Simply don't let users see your access token: you have to create some kind of proxy which will post to your's page wall server-side
Whats the problem if a user who is granting you permission can see his/her own access_token in firebug. Firebug is on client side only. Also, official javascript sdk gives access_token to client. I dont think its bad.
User can always see his/her own password :) . What is bad in it ?
You should care about sniffing access_token over network. As #Juicy suggested use https to overcome that situation.
Edit after reading comment:
In your situation, I would suggest not to use javascript/ajax.
Also, I would recommend to use an sdk over your own php code.
An sdk uses all security measures which should be taken.
Official php sdk:
https://github.com/facebook/facebook-php-sdk

Facebook edge.create

I have added the edge.create event and the event can be fired by the browser as well. But how can I check if the user has liked the page when they come back to the site?
<div id="fb-root"></div>
<script type="text/javascript">
<!--
window.fbAsyncInit = function() {
FB.init({appId: 'YOUR_FACEBOOK_APP_ID', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('edge.create', function(href, widget) {
// OK
});
};
You are going to want to take a look at the signed_request documentation...
This signed request is facebooks method of validating that the user that made the request is indeed "who he/she says they are". It is encrypted and and uses your application secret to decode the values. Once you parse this signed request you will have the data you need.
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 your question is about like for URL that you can get this information only for user who authorized your application and granted user_likes permission. To do so issue next FQL query:
SELECT user_id, url FROM url_like WHERE user_id = me() and url="URL_OF_PAGE"
If your page have an ID in OpenGraph (or you speak about Facebook Page), by querying Graph API for user's likes connection:
GET https://graph.facebook.com/me/likes/OPEN_GRAPH_OBJECT_ID
But if you speaking about Facebook Page and Application running in Page Tab, you don't need anything special to get this information since it will be passed within signed_request (sample php code using PHP-SDK):
$signedRequest = $facebook->getSignedRequest();
$data = $signedRequest['data'];
if ($data['page']['liked']){
// User is liked this Facebook Page
} else {
// User is not yet liked Facebook Page
}

Javascript callbacks work in Firefox but not in Chrome or Safari

I am working with Ejabberd and Orbited and I am having a few issues with my JavaScript callback functions not being called. The following is my JavaScript file where the TCPSocket connection happens and I have two callback functions namely
onSocketConnect: which is called when the Orbited established connection with port 5222 of the XMPP server and
onLoginSuccess: which is called on the successful completion of the xmpp_client.login function
The problem I'm facing is the connection happens successfully but my callbacks get called only when I'm using FireFox and not while using Safari or Chrome. I'm totally clueless about what is causing this problem but I'm sure that the method xmpp_client.login does get called because the user is logged in and is displayed as online in the ejabberd admin console.
TCPSocket = Orbited.TCPSocket;
Orbited.settings.port = 8000;
Orbited.settings.hostname = 'localhost';
document.domain = document.domain;
<script src='http://localhost:8000/static/protocols/xmpp/xmpp.js'></script>
//xmpp.js file is included after this which is available with the Orbited. I have not included the code here.
<% if current_user %>
<script>
notifier = ' ';
user = "<%= current_user.jabber_id %>";
alert(user);
password = '123456';
domain = XMPPDOMAIN;
/* function onLoginSuccess(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
} */
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
}
function onLoginFailure(){
alert('User could not be logged in');
}
function connectSuccess(){
$('.status').html("Connection Successful.");
}
function connectFailure(){
$('.status').html("Connection Failed!");
}
function onSetupNotification(){}
xmpp_client = new XMPPClient();
xmpp_client.connect('localhost',5222);
xmpp_client.onPresence = function(ntype, from) {
alert('Presence message' + ntype + ' From :' + from)
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var domain = XMPPDOMAIN;
$('.status').html('Connected');
alert(user);
if(domain)
{
xmpp_client.connectServer(domain, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
xmpp_client.set_presence('available');
}
}
function send_message(id, msg){
var j_id = id + '#' + 'siddharth-ravichandrans-macbook-pro.local';
alert('jid_id' + j_id);
var status = xmpp_client.msg(j_id, msg);
alert(status);
}
xmpp_client.onMessage = function(jid, username, text) {
alert('message-recieved');
if ( $('.discussion-area').length > 0 ){
$('.discussion-area').append('<div class=\'new-message\'>' + text + '</div>');
return false;
}
}
/* self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
}
self.set_presence = function(status, status_msg) {
self.send(EXT_PRESENCE[0] + full_jid + EXT_PRESENCE[1] + room_jid + EXT_PRESENCE[3] + status + EXT_PRESENCE[4] + status_msg + EXT_PRESENCE[5]);
}
*/
</script>
<% end %>
This is part of the xmpp.js which I got when I installed orbited and in order to test if my requests were actually reaching I added an alert in the login method as follows
...
...
self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
alert("bazingaa");
}
self.connectServer = function(d, s, f) {
success = s;
failure = f;
doma
...
...
Now I have no clue how this got my callbacks and would really appreciate some help on this.
Thanks
Actually I find that removing the xmpp_client.set_presence and moving it to the onLoginSuccess is what seems to have done the trick. The minute I add the set_presence method after the login method call the functionality fails in chrome. So why would that prevent it from invoking the callback on successful login?
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var d = "";
$('.status').html('Connected');
xmpp_client.connectServer(d, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
//xmpp_client.set_presence('available');
}
Help!
I think your problem is related to the Same Origin Policy for Javascript
https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
I'm sure the Safari/Chrome Web Inspector (with Javascript enabled) will verify this in the javascript console
Modern browsers (ie. not Internet Explorer!) get around this issue by implementing Cross-Origin Resource Sharing. But then your Javascript XMPP client library has to implement CORS too
http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
I'm not familiar with Orbited but I have done this type of browser XMPP connections using the Strophejs library and ejabberd's XMPP BOSH connection manager
To get around the Same Origin policy across all browsers you need to employ a proxy
http://flxhr.flensed.com/ (client-side proxy library)
If using apache you can employ a server-side proxy with the ProxyPass directive under the mod_proxy module

Categories