facebook graph api node.js invalid appsecret_proof - javascript

this is my first post so please go easy on me!
I am a beginning developer working with javascript and node.js. I am trying to make a basic request from a node js file to facebook's graph API. I have signed up for their developer service using my facebook account, and I have installed the node package for FB found here (https://www.npmjs.com/package/fb). It looks official enough.
Everything seems to be working, except I am getting a response to my GET request with a message saying my appsecret_proof is invalid.
Here is the code I am using (be advised the sensitive info is just keyboard mashing).
let https = require("https");
var FB = require('fb');
FB.options({
version: 'v2.11',
appId: 484592542348233,
appSecret: '389fa3ha3fukzf83a3r8a3f3aa3a3'
});
FB.setAccessToken('f8af89a3f98a3f89a3f87af8afnafmdasfasedfaskjefzev8zv9z390fz39fznabacbkcbalanaa3fla398fa3lfa3flka3flina3fk3anflka3fnalifn3laifnka3fnaelfafi3eifafnaifla3nfia3nfa3ifla');
console.log(FB.options());
FB.api('/me',
'GET',
{
"fields": "id,name"
},
function (res) {
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
return;
}
console.log(res);
console.log(res.id);
console.log(res.name);
}
);
The error I am getting reads:
{ message: 'Invalid appsecret_proof provided in the API argument',
type: 'GraphMethodException',
code: 100,
fbtrace_id: 'H3pDC0OPZdK' }
I have reset my appSecret and accessToken on the developer page and tried them immediately after resetting them. I get the same error, so I don't think that stale credentials are the issue. My
console.log(FB.options())
returns an appropriate looking object that also contains a long hash for appSecretProof as expected. I have also tried this code with a number of version numbers in the options (v2.4, v2.5, v2.11, and without any version key). Facebook's documentation on this strikes me as somewhat unclear. I think I should be using v2.5 of the SDK (which the node package is meant to mimic) and making requests to v2.11 of the graph API, but ??? In any case, that wouldn't seem to explain the issue I'm having. I get a perfectly good response that says my appSecretProof is invalid when I don't specify any version number at all.
The node package for fb should be generating this appSecretProof for me, and it looks like it is doing that. My other info and syntax all seem correct according to the package documentation. What am I missing here? Thank you all so much in advance.

looks like you have required the appsecret_proof for 2 factor authorization in the advance setting in your app.
Access tokens are portable. It's possible to take an access token generated on a client by Facebook's SDK, send it to a server and then make calls from that server on behalf of the client. An access token can also be stolen by malicious software on a person's computer or a man in the middle attack. Then that access token can be used from an entirely different system that's not the client and not your server, generating spam or stealing data.
You can prevent this by adding the appsecret_proof parameter to every API call from a server and enabling the setting to require proof on all calls. This prevents bad guys from making API calls with your access tokens from their servers. If you're using the official PHP SDK, the appsecret_proof parameter is automatically added.
Please refer the below url to generate the valid appsecret_proof,and add it to each api call
https://developers.facebook.com/docs/graph-api/securing-requests

I had to deal with the same issue while working with passport-facebook-token,
I finally released that the problem had nothing to have with the logic of my codebase or the app configuration.
I had this error just because I was adding intentionally an authorization Header to the request. so if you are using postman or some other http client just make sure that the request does not contain any authorization Header.

Related

Why my geoip query doesn't work in my production server?

I'm getting a hard time making Maxmind's geolite2 geolocation work on client side.
First I found this page: https://dev.maxmind.com/geoip/geolocate-an-ip/web-services?lang=en
And tried to use the urls in the curl command with authentication with my generated license key:
let geoData = axios.get('https:///geolite.info/geoip/v2.1/country/me?pretty', {
auth: {
username: <myuser>,
password: <mylicensekey>
}
});
this works in node but in client-side I get a CORS error.
then I found this other page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
It worked but I didn't want to use a non-npm packaged lib, so I inspected the lib's source-code and saw it call a different url from above:
https://geoip-js.com/geoip/v2.1/country/me?
trying this new url I saw it worked only WITHOUT authentication. I didn't understand why but anyway... it worked. Until I send the code to production at least.
With localhost it worked ok, but in production I get an error saying I have to register my domain.
The link provides in "register your domain" in this page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
leads to https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains which asks me to enter the paid service registration page: https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains
Is that it ? Client-side geolocation is only available as a paid service ?
So I want to know:
If there is a way to register domains for the free service, where do I register my domain?
If I can use https://geolite.info/geoip/v2.1/country/me?pretty url with id and license key in client-side, how to I get rid of the CORS message ?
I want to get the data without sending the user's IP, like when we access https://geolite.info/geoip/v2.1/country/me?pretty with id and license key.
Currently I want to use MaxMind's free data.

How to get Azure AD access token in Static Web App?

I have a vanilla Vue.JS SWA that uses a standard Azure AD authentication via these settings in staticwebapp.config.json:
"auth": {
"identityProviders": {
"azureActiveDirectory": {
"registration": {
"openIdIssuer": "https://login.microsoftonline.com/common/v2.0",
"clientIdSettingName": "AZURE_CLIENT_ID",
"clientSecretSettingName": "AZURE_CLIENT_SECRET"
}
}
}
}
An app with AZURE_CLIENT_ID is registered in Azure AD. Authentication is called via standard
/.auth/login/aad
endpoint. I can successfully log in and log out. "/.auth/me" endpoint returns clientPrincipal object with all user details (roles, id, etc) and claims.
Now I want to call MS graph API https://graph.microsoft.com/v1.0/me, but don't know how to get the access token to set the Authorization header in the request. I can see that there is a AppServiceAuthSession cookie is set, however it is not a token.
I have seen this https://stackoverflow.com/questions/59860238/how-to-convert-azure-cookie-appserviceauthsession-to-a-valid-oauth-jwt-access-to , however reconstructing the whole auth flow looks unnecessary as I am logged in already.
Will appreciate any advice. Many thanks!
Tried to all MS Graph API as is, but as expected, got "message": "Access token is empty."
Also had a look at azure/msal-browser module in a hope to get the token silently, but it looks super complex and badly documented for a JS novice like me.
The following microsoft document shows getting the access on behalf of the user, you can refer this DOC to get the access token.
Hope this helps.

Get an access token without being connected to facebook

I need to retrieve a facebook page's list of posts (feed) using their javascript SDK, just like they explain in their docs: https://developers.facebook.com/docs/graph-api/reference/v2.4/page/feed
/* make the API call */
FB.api(
"/{page-id}/posts",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need it to be my website's "news section", so users should see it even if they are not connected to facebook.
The problem
Cool, but there is a problem... It returns: An access token is required to request this resource.
Holy cow... I'd like to get some access token for you #facebook, but my app doesn't make use of your authentication tools/plugins.
ANYWAY, I tried with FB.getLoginStatus(); but doesn't work, because the only way it can return an access_token is if the user is actually connected to the application. My users may not even be logged to facebook!
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
I've already payed a look to this SO question, but it doesn't solves my problem, simply because there are no such "generic tokens".
I've also read https://developers.facebook.com/docs/facebook-login/access-tokens/ and that also relies on tokens generated through facebook login methods... So, can't I display a list of fb page's posts in my website, without being connected into facebook, hence an application?
ADD: My app is build with angularJS, I'm not dealing with server-side code. I shall rely purely on javascript methods.
You could either use an page or an app access token, but as you'd be using them on the client-side, neither of them are an option.
See
https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
I'd strongly recommend to build a simple server-side script (PHP for example) to proxy the request to the Graph API. You could then call this via AJAX for example and load the posts asynchronously (and alse get rid of the FB JS SDK!). There is NO way to handle this in a secure manner if you don't want to use FB Login for all of your users (which also doesn't make much sense IMHO).
I think it's straightforward :)
Since pages' posts are always public, it only needs a valid access token to retrieve page posts.
Quoting what you've written:
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
You only require an access token.
My suggestion would be;
- Generate an access token for yourself (no extra permission needed)
- request page-id/posts
This way you don't require other users to be connected to facebook, you can simply requests page-id/posts to retrieve posts with access token you generated for yourself.
I hope it solves your problem :D
TIP: As long as posts are public, you only require a valid access token, it doesn't need to be user or page specific.

Can't Post to Facebook Page using JS

Okay what I want is to post to the Facebook Page as an Page(This is developing mode application only viewable to ne).
I have done with Facebook login.
So basically I ask for 2 permissions and they are
Manage Pages
Publish Pages
I can post to the page using the Facebook graph explorer tool but can't via my Javascript code.
Here is the code that I write using JS. This code is written inside a function.
FB.api('me/accounts', function(response){
token = response.data[0].access_token;
post_with_token(token);
});
function post_with_token(token){
var message = $('#post_body').html();
var page_id = 'page_id';
FB.api('page_id/feed', 'post',
{ message : message,
access_token : token},
function (response){
console.log(response);
});
The error object in the console says this
message: "(#200) The user hasn't authorized the application to perform this action"
Both the apps My and Graph explorer have the same permissions granted.Is any new permission to be asked. I am unable to figure out what exactly the problem is.Correct me if I am wrong anywhere.
I got the answer that I posted below but didn't got why I need additional permission.?
publish_pages has only been introduced with Graph API version 2.3.
Before that, publish_actions was used to allow posts on pages by the page as well – now with v2.3, they have made that into two separate permissions. publish_actions is for everything you publish as/in the name of a user, and publish_pages is for publishing as a page.
Graph API Explorer has API version 2.3 selected by default – that is why your call was successful there. Most likely, with your own API call from your JS code, you did not use v2.3, but specified a lower API version when initializing the JS SDK.
So just specify version: 'v2.3' in your FB.init parameters (see Basic Setup section in JS SDK docs), and it should work fine with publish_pages.
Okay I solved the problem . I have to ask for publish_actions permission also. So I asked through the Login Dialog and used the same code as above to post to the page!
The error implies exactly what it says. They've designer their API so it's not going to let you post without proper authorization first.
Facebook provides a guide on how to give proper authorization to your registered app

Yammer JS SDK — problems with CORS

It seems like something has changed on the Yammer side, because my app (not yet published to the Yammer Global App Directory) has stopped working, resulting in an obscure CORS error, that doesn't tell a thing about the problem.
So the workflow is very simple —
I'm ensuring that user is logged in by calling getLoginStatus() (which pops-up a window and immediately closes it. Irritating, but can live with that)
Sending a request to messages/in_group/ID.json wrapped in a yam.platform.request, as suggested by the Yammer JS SDK manual
Here's the console screenshot:
In the Yammer App settings there's a single Javascript Origin, which is https://buzztale.com, which is exactly the one, the request is made from.
This happened before, but then disappeared itself (really confusing). And now it seems to be back…
Hope somebody has any suggestions regarding this issue. In order to get to the app, here's the URL — https://buzztale.com/yammer.
Same here my dev app started failing sometime today.
It seems that all of the login end points are working as expected however the messages feed is giving me CORS errors.
yam.platform.request({
url: "https://api.yammer.com/api/v1/messages/my_feed.json",
method: "GET",
success: function (user) { //print message response information to the console
console.log("The request was successful." + user.messages);
},
error: function (user) {
console.log("There was an error with the request.");
}
});
Yeah, I'm seeing this on our end too. Seems to be just the GET requests with the messages api endpoint. Like POST / DELETE and Message POST seem to work correctly.
This issue appeared to me around 4PM PST yesterday (7/22/14).
This was a known issue with a recent change on our side, and we have
pushed a fix to production today. Please let me know if it still isn't
working for you. — Nick
So it is an issue on the Yammer side and we can just hope for it not to appear again.
I am seeing this with the notifications endpoint as well. I noticed that the CLIENT_ID is not being appended to the call
https://api.yammer.com/api/v1/streams/notifications.json?&_=xxxxxxxxxx

Categories