Using app access token had previously been asked in this question (How to use Facebook appAccessToken with Spring Social) and Craig Walls gave a good explanation why the spring-social API should be user-based for most cases.
I have a scenario, however where I would like our server-side application to make a couple of queries that should not require user-specific permissions. I picked a random public page for examples below
I would like to:
View details about a public page by alias/id
https://graph.facebook.com/v2.0/121727254549188
https://graph.facebook.com/v2.0/peterstevensmotorcycles
View posts for a public page by alias/id
https://graph.facebook.com/v2.0/121727254549188/posts
https://graph.facebook.com/v2.0/peterstevensmotorcycles/posts
Search for pages
https://graph.facebook.com/v2.0/search?q=Peter%20Stevens%20Motorcycles&type=page
When I test these in the Graph API explorer (https://developers.facebook.com/tools/explorer) using an App Access Token they work fine. App Access Token is obtained by hitting https://graph.facebook.com/v2.0/oauth/access_token?client_id={app-id}&client_secret={app-secret}&grant_type=client_credentials and replacing client_id and client_secret with my Facebook client credentials.
Our application would like to have the ability to make these for any given name so we can make queries about a company's presence.
We will have similar requirements for Twitter, LinkedIn and others so I just wanted to check if there are any means to do this in the current API or whether it will not suit our requirements.
You do not need to fetch an app access token - you can actually use the app id and secret separated by "|" as the access token. - You can see it at the bottom of the app access token section in the documentation: https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
Spring Social's Facebook API binding does not (yet) support v2.0, but that's something I'm working on right now...so hopefully soon. Once that's complete, there'll certainly be some operations that work only with user access tokens and some that only work with app access tokens, and some that will work with either (FWIW, Twitter's API has a similar set of circumstances).
Keep an eye on the project in GitHub or follow #SpringSocial on Twitter to know when the v2.0 stuff is available. (I'd appreciate any help I can get in testing it.)
Although it makes no sense at all to obtain your FacebookTemplate via the connection framework for app token requests (connections are, by nature, a user-oriented concept), you can always construct a FacebookTemplate wherever you need it, giving it an app access token obtained via OAuth2Template's authenticateClient(). You can certainly do that now with the v1.0 API binding, but I'm uncertain what ops an app token would work with.
FWIW, as I'm working on the v2.0 API binding, I'm starting to sense an opportunity for FacebookTemplate to carry two tokens: A user token and an app token. This way you can perform app-centric requests even from a FacebookTemplate obtained from the connection framework. Then the only time you'd ever want to construct a FacebookTemplate manually is if there are some operations for which either kind of token will work, but the results would be different depending on what type of token is used.
Related
I'm building a REST API with Laravel and now I have an URL like
api.example.com/posts/3/comments
Now I'm wondering how to secure this API because as it's done now, anyone trying to make a GET, POST, ... request on this URL will get positive results.
I want this API to be available to authorized apps only (like Facebook API). For now, those apps are just my website and my iOS app.
I'm thinking about creating a table applications to store application's keys. But I don't know how to authenticate an app without publishing it key (which is obviously insecure).
Any suggestion? Thank you.
I would recommend that you use something like JWT. Using it, you create and store a token locally on the device, then every time someone makes a call to the server, you check the token and make sure that they are who they claim to be. You can store tokens for expiration if you like. They're typically used in stateless apps, so you will need to move away from the concept of a server session. You can use Middlewares to filter HTTP requests entering your application.
I try search the the pages and the events by two different calls (still using Graph Explorer):
search?fields=name&q=warsaw&type=page
search?fields=name &q=warsaw&type=event
The second (events object) works only with user token. When I generate app token there is invalid token error. Is it possibile to get results for second query with app token? It’s important for me, I need use it in my own code.
Can I generale user token within scripts (HTTPS request),
OR generale long time user token (I mean user token for my own profile)
OR (most desired solution) get results for secong call above (type=event), by app token?
UPDATE:
Ok, sory, so it’s clearly that app token doesn’t support search for event (but I still don’t understand why – events, such as page is public object and it doesn’t contain a private data).
I’m going to clarify another way. I’d like to download information about events and use it in my own site (database) as public. This operation’s objective is create database of FB events (something like Eventbrite). So I need make that set as public (belongs to app/site, not user profile).
I know that’s not a standard usage of Facebook API, but if it infringes the FB policy, please write me – I haven’t find clearly statement for that. I’ve ask about it here Terms of use data from Facebook API. I guess it’s legal.
Now. I can retrieve events by page node (get all events for each page), but it’s strongly uneffective – only few page of whole are the event’s organisators. I need explore directly events.
Is there any solution for that problem?
Why don't you just consult the Facebook docs? It clearly stated in
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2#search
that
Searches across Page and Place objects requires an app access token.
All other endpoints require a user access token.
So, no, you can't just use an app access token to search for events.
Regarding login, see
https://developers.facebook.com/docs/facebook-login/v2.2
I implement some facebook related stuff and accessing graph api for that pourposes. But for implement Integration testing I need a simple strategy to get access_token. So I create test user for that. How could I get access_token only with server side involved, without including browser in the chain. Ideally I just need to exchange login/password to the token.
Correct workflow loooks like this:
According the correct answer, there is special tests users provided by facebook.
To to be able to tests system properly you need to do the following flow
Get application access token
Request application's tests user's via "GET /{app_id}/accounts/test-users"
Parse response and extract access_tokens for each user from that response.
You can't exchange the login/password for an Access Token, but you can create test users programmatically. Have a look here:
https://developers.facebook.com/docs/graph-api/reference/v2.0/test-user
https://developers.facebook.com/docs/graph-api/reference/v2.0/app/accounts/test-users
How to get an access token with the right permissions for a test User
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/permissions/
Short answer: You can´t.
Server side you can only get an App Access Token, Page Access Token or extend an existing Access Token.
So it depends on what you need to achieve, if you just want to get public stuff from a Facebook Page, even an App Access Token may be good enough. But you cannot create User Access Tokens server side.
It may be possible with real test users created via the Graph API itself though, see Tobis answer for links about that. But it is definitely not possible with username/password.
My question is related to, but not exactly, this question.
I am currently working on a business directory Web site (similar to Yelp), in which businesses have their own pages. Let's call this app DIRECTORY_APP.
Businesses might want to have their latest Facebook status update shown on their pages hosted on our directory. Let's pretend we have a business named BIZ_1. The assumption is that those pages are public pages.
Apparently the Facebook Graph API can be used for this purpose. So I can send a request to Facebook to retrieve the latest status updates for BIZ_1:
https://graph.facebook.com/BIZ_1_PROFILE_ID/posts?
access_token=DIRECTORY_APP_ACCESS_TOKEN
&callback=callbackName
However, if I use this from the client side, our Web site's access token will be exposed to the public, so this is not a reasonable solution.
Now in the aforementioned question, Anatoly mentions that we can retrieve the access token by sending this request first:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
However if someone inspects the Network log, this will also expose our Web site's access token (is this correct or is this a different type of access token?). This solution also exposes our web site's app secret (is this safe?).
So to summarize, what's a safe way in which I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook?
I can retrieve the latest status update of a Web page from client-side without asking the browsing user to first log in to Facebook
You cant do that without login.
And I guess access token is not exposed.
Maybe the smart trick here is to use a social plugin. The Like Box will do what you want, without any issues. But, it's not greatly customizable. Even so, it's possible to get it looking nice on a page!
It also skips any login issues you mentioned.
I found the answer after some Googling. In short, the answer is no.
And here's an excerpt from Facebook:
Security Best Practices
App Secret and App Access Token
The App Secret is used in some of the Login flows to generate access tokens and the Secret itself is intended to secure usage of your App to only those that are trusted. The secret can be used to easily create an App Access Token which can make API requests on behalf of any user of the app, which makes it extremely important that an App Secret is not compromised.
Therefore the App Secret or an App Access token should never be included in any code that could be accessed by anyone other than a developer of the app. This applies to all methods of code that are not secured like client-side code (such as HTML or Javascript) or native apps (such as iOS, Android or Windows desktop apps) that could be decompiled.
We recommend that App Access Tokens should only be used directly from your app's servers in order to provide the best security. For native apps, we suggest that the app communicates with your own server and the server then makes the API requests to Facebook using the App Access Token. For this reason, if your 'App Type' under Advanced Settings in the App Dashboard is set to Native/Desktop we assume that your native app contains the App Secret or an App Access Token in the binary, and we do not allow calls signed with an App Access Token to proceed. The API will behave as though no access token was provided.
If your App Secret is compromised, you should reset it immediately in the Basic Settings of your App Dashboard.
I created an app and an offline access token so I could display a news feed on my website without requiring a Facebook login. I created two test versions in PHP and JavaScript that work fine. But I took down the JavaScript version because I was concerned about the lack of security in explicitly stating the access token in a client-side script. Is server-side the only way to go for security reasons?
I think you are correct to take out your access token from javascript. As long as that access token is valid - even if it hasn't been obtained with offline_access permissions - it can be used to perform actions on behalf of that user/app/page. All you need to make calls is the user/app/page ID which is easily obtainable and a valid access token...
I recommend you leave your access token management to your server-side scripts. Perhaps making ajax calls to refresh the posts at regular intervals...