I am building a facebook game using ASP.Net MVC3. (More like Mafia Wars and less like Farmville in terms of technology and look and feel).
Almost all of the actions of the game will be triggered by Javascript (which calls a REST api) that we have written.
Now, our game authentication is done using Facebook's JS SDK and we also ask for offline access permission. So we save the auth_token in our DB the first time a user signs up.
I want to know what would be the best way to access the id of the user for operations performed within the application from the point of view of security (and making it hard for people to spoof ids)
I know of the following ways:
Store it in a Global javascript variable and load it on every page load using the JS SDK. (bad idea because this can easily be changed in Firebug)
Read the value from server side using the fbs_[app-id] cookie that is set. (again, I was able to change the value in the cookie which got posted to the server)
Use the C# SDK and do an API fetch (for /me) to get the ID using the auth_code which is supplied in the cookie (by far the safest way - but also the slowest)
Any pointers would be greatly appreciated.
Also please let me know if I am getting excessively paranoid about this.
I am sure there must be a clean, simple, secure method which I have overlooked!
Thanks.
I guess I'll just put down what we are doing - incase someone stumbles upon this later.
I checked out Zynga's Mafia Wars and found my facebook id peppered at almost 6 to 7 places throughout the page in the HTML code.
I guess one could try fooling around and modifying it using Firebug - but the quantity of obfuscated javascript out there, one would need to be decently motivated to do it.
However, what we have ended up doing is follows.
Our game asks for offline access to the user - so the access token that we get in the first login, is saved in our DB.
Then everytime the user performs an action, the facebook cookie associated with the account is returned to us out of which we pull out the access token.
We then do a lookup on our own DB for the user id corresponding to this access token.
If the user id is not found (for a new user, say), we do a GET("me") using the facebook api to get the user id.
It is slightly ineffective - but I guess will do for the time being. Will update this if we end up doing something else. Maybe we just are over analysing things.
Related
I am trying to build an google chrome extension for Facebook.
I should be able to access the facebook api without actually asking the user to authenticate explicitly for my extension.
Is there a way to do that?
The answer is yes and no.
Yes: You can "read" as much as a they have loaded in their page through a Content Script that reads the window document. A good example could be the following.
In the manifest.json
"content_scripts" : [{
"matches" : ["http://www.facebook.com/*"],
"js" : ["js/vendor/jquery.min.js", "js/content.js"],
"run_at" : "document_end"
}]
In the js/content.js
var document = jQuery(window.document);
var posts = document.find("div[role='article']");
and then you can read as much as you wish of the user, or well, as much as the page loads. You could have some sort of timeout mechanism that checks whether there's new content in the page, or new elements were added to the dom, but at the end the user has to scroll down to load information, or you can hack this through Javascript.
No (and why you shouldn't): I'm not a legal guy, but I had been developing long enough to know that whenever a platform gives you an API, you are supposed to use it. Why? Because they can control what information you are reading, and they can protect their user information that way.
This is actually a delicate line, because sometimes you can enhance a website experience without necessary using a website API (and sometimes they don't even have one). This is then even appreciated if you are actually improving the user experience. In this case thought, I wouldn't do it though, because:
It's Facebook, I'm pretty sure they have in some Terms of Service a line where they describe what I just wrote about reading user's information through external scripts.
External applications that crawl your data have had bad reputation since day one (automatic posts, scamming, scrapping information, etc)
Facebook API is now based in Oauth2, which in its foundation was made to protect the users; through a token denial, a user can stop at any time an application from reading his/her data, while your application has no mechanism for that (uninstall may be it, but you may have stored already his/her data)
It's not that hard asking for permission and you would be saving yourself a lot of trouble.
How to do it the right way? Request an application ID, and load the facebook SDK in a Background Page. Prompt the user permissions (yes, the right way includes asking the user for permission on what you can read so he/she can deny you access to them if you misbehave) and then query the Facebook API with that.
Think about it. You can create an extension that reads the content of a user page whenever he logs into his/her bank. Or his email. Actually, anything that a user sees inside a browser window can be retrieved by an extension. This is extremely dangerous to the user if there's no control over which information is being taken from him!
Ask for permission first. Don't be THAT guy ;)
I found the section below on Facebook Developer. Does Facebook provide a way for me to browse the posts by my users, or do I need to store the post ID and write my own dashboard?
It depends which SDK you are using. In general, Facebook does not offer a solution on their own, and if you are using the JavaScript SDK for the postings there is no way to get to the message.
That being said, the only way to get the messages posted via the JS SDK is the following:
The user has to authorize your app
You have to store the access token of the user
You have to store the Post-ID of every post so you can make an API call to get the message
Remember that those user access tokens are valid for ~2 hours only, so you have to use an extended one (up to 60 days valid). After those 60 days there is no way to read the messages anymore, so you would have to store them in your database if you need/want them later. Also keep in mind that the user can remove your app and invalidate the token.
If you are using the PHP SDK for posting (which only works for users who authorized your app), then you can just store the message value in your database because you need to get the message anyway (from a textfield, for example). But be sure to tell the user what you will store, also why and for how long, for privacy reasons.
Summary: The only way to do this (without getting problems with access tokens) is to let the user authorize your app, after every publish you have to use the new post id to get the message with an API call and to store it in your database. This is valid for the PHP SDK and the JS SDK.
Yep, there's no way rightnow, by which you can view the posts published through you're app. The only way you can achieve this is by storing the post_id for every published post, and create a script that will fetch the posts data, when provided with the post_id's
I want to create an iPhone app that displays (among other things) a specific Facebook wall. For a good user experience I didn't want an app that required the user to have a Facebook account and I didn't want to force the user to have to log in to Facebook to see the latest "news" in the app. I started out by getting the wall RSS feed and tried parsing it ... I can "see" all the data I need ... but that is getting complicated quickly and has too many variables that are making the final results less than stellar. I have read through the Facebook iOS programming tutorials and it seems to me like the SDK forces the user log in, which I don't like.
My question ... Is there a way to use the Facebook SDK with hard coded profile credentials to access a specific wall without forcing the user to login? If possible, is that a recommended approach? Any other ways to skin this cat?
I have read through the Facebook tutorial and searched through many postings on this site but haven't found an answer to this ... sorry if this a newbie question and has already been answered.
Item I.2. of the Facebook API policy list says
You must not include functionality that proxies, requests or collects
Facebook usernames or passwords.
It sounds to me like that's what you're proposing to do; i.e., the user will be able to see a certain wall, but using hard coded credentials (not their own). In other words, your credentials are proxying for the user.
I do not know if it is technically possible to do this (I imagine it is) but I don't think it's a good idea, and I do think it's a violation of the Facebook API terms of service.
First you need to get the a access_token by parsing your app id and secret.
https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET
Then send following request to get the data you want. Note that only public data will be accessible.
https://graph.facebook.com/FACEBOOK_USER_ID/?access_token=ACCESS_TOKEN
I have an application that is retrieving data from Facebook. Users authorize the application to read and write to their pages, and we read their data and post to it from our application. All interaction occurs via the PHP interface that Facebook supplies.
For the last few months our application has been performing this task flawlessly. However in recent days we have started noticing an issue with certain pages.
We go out and retrieve data for a specific page, and we no longer get any data. Instead Facebook returns us an empty result. This obviously causes problems in our application which needs to read this data.
We can still write data just fine.
I am at a point where I'm not sure what this could be. Any common scenarios or recent Graph API issues that could cause this?
This sounds odd. The only thing that comes to mind is that the page owner has put a restriction on the audience for their page, which would then require you to pass in an access token to access data about the page. An example would be a beer company that wants to limit access to their FB page to users that are older than 21. Since there is a restriction on who can access the page content, we enforce that restriction on the FB platform. In this case you would need to pass in the access_token of a user who is 21 or older to access the page details via the graph api.
Adding to Jeff's answer, I found that any kind of restriction whatsoever will return a blank data object. I was banging my head on every single setting on my company's page and found that we had it set to only show in certain countries (Manage Settings > Country Restrictions). Removing all of them from the list started to return all the data we needed.
Let's say I own/control a Facebook page where events are posted. I'd like to display these events on another website (In my case, a WordPress blog, but that's not the important part) on an "Upcoming events" page.
What I'm unsure about is: Is the Facebook API usable "externally" like this? I've downloaded the PHP library and have a demo app running that works from within Facebook (i.e. emitting FBML that facebook.com interprets and displays to the logged-in user), but in my case I want a third party (my web server) to query Facebook every so often, rather than the site visitors directly requesting data (HTML/JSON/etc.) from Facebook itself.
Is this sort of thing possible with the Facebook API? How will my web server authenticate itself? What information do I have to store?
Note: I'm looking for information more at a "sequence diagram" conceptual level, not just asking for code. That part I can figure out myself. ;) Unfortunately, Google and the FB developer wiki have not been entirely forthcoming. What do I need to know so I can start coding?
This is a basic overview of how I've done it for a few of my clients who wanted similar functionality:
Create a pretty basic app that prompts for Extended permissions, specifically "offline_access" and whatever else you need
Store the resulting Session Key in your database with the UID
Create a secure, authenticated webservice for your app which allows you to get the info you need for a UID that you supply, using the session that you've stored in your database
On the website make requests to your app's webservice, being sure to cache the results for a certain period of time and only make a new request to your webservice once the cache has expired (I use 5-10 minutes for most of mine)
So basically your Facebook app acts sort of like a proxy between the website and the user, doing all of the authenticating and requesting using legitimate means.
I've used a webservice because I only wanted to maintain one Facebook app for multiple client's needs. It works like this (in a not-very-awesome ASCII art diagram):
Facebook User 1 \ / Client Website 1
Facebook User 2 --- Facebook App --- Client Website 2
Facebook User 3 / \ Client Website 3
Note: I've only done this for users, not pages, so your mileage may vary.
You can do Events.get with the Facebook API then supply the page/profile ID you'd like to get the events for. Depending on how your page is setup you may have to authenticate, simply use your Facebook account, since you should have access to all the events. oh and make sure you do plenty of caching so your not hitting Facebook on every page load.
AFAIK other than user info, you can't fetch any other data from facebook.
But you can try it other way - say create an app that stores events and other relevant information on a webserver and then your other website can easily access that info.