Facebook package support for login-requests with appsecret_proof

794 views
Skip to first unread message

Jan S

unread,
Jul 8, 2014, 3:10:39 AM7/8/14
to meteo...@googlegroups.com
Hey,

If you're developing a Facebook App and go to Settings-> Advanced (https://developers.facebook.com/apps/<YOURAPPID>/settings/advanced/) you can activitate a flag called 
App Secret Proof for Server API calls - App must submit a proof of app secret

This is securing server request by hashing access tokens with the app secret (sha 256). More information about the appsecret_proof can be found on this Facebook page

So if this flag is activated the loginWithFacebook-method will fail with a internal server error:
at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56)
    at _.extend.protocol_handlers.method (packages/livedata/livedata_server.js:641)
    at packages/livedata/livedata_server.js:541
{"line":"230","file":"oauth_server.js","message":"Error in OAuth Server: Failed to fetch identity from Facebook. failed [400] {\"error\":{\"message\":\"API calls from the server require an appsecret_proof argument\",\"type\":\"GraphMethodException\",\"code\":100}}","time":{"$date":1404212340557},"level":"warn"}
Exception while invoking method 'login' Error: Failed to fetch identity from Facebook. failed [400] {"error":{"message":"API calls from the server require an appsecret_proof argument","type":"GraphMethodException","code":100}}
    at getIdentity (packages/facebook/facebook_server.js:93)
    at Object.isJSON [as handleOauthRequest] (packages/facebook/facebook_server.js:10)
    at OAuth._requestHandlers.(anonymous function) (packages/oauth2/oauth2_server.js:8)
    at middleware (packages/oauth/oauth_server.js:89)
    at packages/oauth/oauth_server.js:62

Here is a code snippet where the appsecret_proof has been implemented.

Would be a great thing to use it in Meteor. Comments, Concerns?

Thanks

Jan S

unread,
Jul 11, 2014, 5:02:47 AM7/11/14
to meteo...@googlegroups.com
So basically the following function needs to be changed to:

var getIdentity = function (accessToken) {   
  var config = ServiceConfiguration.configurations.findOne({service: 'facebook'});
  if (!config)
    throw new ServiceConfiguration.ConfigError();
 
  var crypto = Npm.require('crypto');
  var hmac = crypto.createHmac('sha256', config.secret);
  hmac.update(accessToken); 
 
  try {
    return HTTP.get("https://graph.facebook.com/me", {
      params: { appsecret_proof: hmac.digest('hex') }}).data;
  } catch (err) {
    throw _.extend(new Error("Failed to fetch identity from Facebook. " + err.message),
                   {response: err.response});
  }
};

Haven't tested it yet. I'm also not sure if the NPM.require is placed correct and maybe it would be better to constantly save the appsecret_proof if querying needs to be done again (appsecret_proof has to be updating if access_token needs to be renewed). And I never did a Github Pull Request before ;)

So maybe someone could help me out a bit. Thanks 

Emily Stark

unread,
Jul 11, 2014, 11:45:49 AM7/11/14
to meteo...@googlegroups.com
Hi there,

Can you confirm that sending `appsecret_proof` on requests works if you have not set the "require app secret proof" flag? I want to make sure that if we make a change like this, we aren't requiring people to set that flag.

Thanks!
Emily


--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core.
For more options, visit https://groups.google.com/d/optout.

Jan S

unread,
Jul 11, 2014, 2:05:23 PM7/11/14
to meteo...@googlegroups.com
Hey,

Yeah you're right I forgot to mention that it will work without activating this flag (e.g. default enabled in the Facebook PHP SDK).
If you set the flag Facebook will only accept requests that are using the appsecret_proof parameter... sorry didn't clarified that.

Thanks

Emily Stark

unread,
Jul 11, 2014, 9:12:55 PM7/11/14
to meteo...@googlegroups.com
Ok, that's great then! Your patch looks good to me, except for a couple small things:
1. You could do the Npm.require at the top of the file (where we do Npm.require('querystring'))
2. You'll want to use `OAuth.openSecret(config.secret)` instead of using `config.secret` directly. (The secret might be encrypted, which `openSecret` detects and decrypts.)

I don't think that you need to save the appsecret_proof in the database; it's a very quick thing to compute, so users can always recompute it and save it themselves. It's probably better to avoid having it in the database if possible -- and if we did put it in the database, we'd certainly want to encrypt it if the oauth-encryption package is loaded.

Emily

Jan S

unread,
Jul 12, 2014, 6:39:56 AM7/12/14
to meteo...@googlegroups.com
Ok thanks, changed it a bit here is a gists with the code of facebook_server.js

Tested it on https://fb-appsecretproof-test.meteor.com/  (btw this fb app has not ticked the "appsecret_proof required"-flag, but that doesn't affect anything)
or here (basically just html with loginButtons + changed facebook package)

But it isn't working correctly. There is no error occuring, but the popup window doesn't close...Looks strange to me!

Anyone ideas? :/

Jan S

unread,
Jul 17, 2014, 4:03:11 AM7/17/14
to meteo...@googlegroups.com
Ok there seems to be a problem when deploying to meteor.com.... Tried the original package and popup is not closing.
Created new project added accounts-ui & accounts-facebook and entered {{>loginButtons}} to html file. Also entered my appid and secret in the browser. 
After hitting signin popup does not close. Can anyone confirm that? Send me an url and I will give you a appid and secret of a test app.
Reply all
Reply to author
Forward
0 new messages