Created
November 3, 2010 19:50
-
-
Save chanon/661597 to your computer and use it in GitHub Desktop.
Facebook iframe Canvas App Authentication in node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var querystring = require("querystring"); | |
var base64ToString = function(str) { | |
return (new Buffer(str || "", "base64")).toString("ascii"); | |
}; | |
var base64UrlToString = function(str) { | |
return base64ToString( base64UrlToBase64(str) ); | |
}; | |
var base64UrlToBase64 = function(str) { | |
var paddingNeeded = (4- (str.length%4)); | |
for (var i = 0; i < paddingNeeded; i++) { | |
str = str + '='; | |
} | |
return str.replace(/\-/g, '+').replace(/_/g, '/') | |
}; | |
var getAuthorizeUrl = function() { | |
var oauth_url = 'https://www.facebook.com/dialog/oauth/?' | |
var options = { | |
client_id: YOUR_APP_ID, | |
redirect_uri: 'https://apps.facebook.com/YOUR_APP/', | |
scope: COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES | |
}; | |
// for scope see https://developers.facebook.com/docs/authentication/permissions/ | |
// eg. it could be "publish_stream,email" | |
return oauth_url + querystring.stringify(options); | |
}; | |
app.get('/fb', function(req, res) { | |
var signed_request = req.param('signed_request'); | |
var parts = signed_request.split('.'); | |
var sig = base64UrlToBase64(parts[0]); | |
var payload = parts[1]; | |
var data = JSON.parse(base64UrlToString(payload)); | |
if (!data.user_id) { | |
// send over to authorize url | |
res.send("<script>window.top.location='" + getAuthorizeUrl() + "'</script>"); | |
} | |
else { | |
// lets verify | |
if (data.algorithm.toUpperCase() !== 'HMAC-SHA256') { | |
res.send('Unknown algorithm. Expected HMAC-SHA256'); | |
return; | |
} | |
var secret = YOUR_APP_SECRET; | |
var hmac = require('crypto').createHmac('sha256', secret); | |
hmac.update(payload); | |
var expected_sig = hmac.digest('base64'); | |
if (sig != expected_sig){ | |
console.log('expected [' + expected_sig + '] got [' + sig + ']'); | |
res.send('Hello, this is my app! you are CHEATING! .. expected [' + expected_sig + '] got [' + sig + ']'); | |
} | |
else { | |
res.send('Hello, this is my app! you passed verification and are ' + data.user_id); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So to explain, what it's doing: First it checks if there is a user_id in the signed_request. If there is no user_id, that means the user hasn't authorized the app. So we redirect them to the facebook authorization page so they can authorize our app. At the same time we send some permissions to that page through the "scope" option to request from the user.