Is it possible to get users extendest tokens via js api?
If it isn't what about getting multiple users token with single query?
I get tokens like this;
https://graph.facebook.com/oauth/access_token?client_id=xxx&client_secret=xxx&grant_type=fb_exchange_token&fb_exchange_token=".$u[token]
You can't issue an ajax request to that url since ajax requests are limited to your domain (cross-domain security policy), but you might be able to use the facebook javascript sdk, though I'm not sure it will work.
Something like:
FB.api("oauth/access_token", "get", {
client_id: xxx,
client_secret: xxx,
grant_type: "fb_exchange_token",
fb_exchange_token: currentToken
}, function(response) {
console.log(response);
});
Even if this works, it's not something that you should use since you have to include the app secret with the request, and since you want to do so from the client side it means that the app secret won't really be a secret no more.
Also, what's the point of doing that? As long as the user is interacting with your app, you can simply use what it states in Handling Invalid and Expired Access Tokens:
Desktop Web and Mobile Web apps which implement authentication with
the Javascript SDK
Calling FB.getLoginStatus() or ensuring status: true is set when you
call FB.init() means that the next time a user lands on your
application and is signed into Facebook, the authResponse object you
are passed as a result of those calls will contain a fresh, valid
access token.
In this case, its simply the act of the user using your application
which implicitly generates a new access token.
As for your other question, the facebook api has what's called Batch Requests, which let you make a few api queries in one request, but I'm not sure that it work for the relative path "oauth/access_token", but you are welcome to try it.
Related
Scenario/setup
I have a web application that allows a user to log in using either Facebook or username+password. The user is able to link Facebook to the account, in which case the backend stores an offline Facebook access_token token, so that it can make various requests. This all works fine.
Now I want to use features of the Facebook Javascript SDK (specifically open the requests dialog), but I do not want the user to be forced to log into Facebook on the client if he just logged into the application using username/password.
Question
Having a valid access_token on the server, I want to pass this token to the Facebook javascript SDK, so that no matter how the user logged into my web application, he is now "logged in" to the Facebook account associated with his account, as far as the SDK is concerned.
I have found a few vague examples, but none that explain in detail how to do it entirely.
Currently I am thinking the way to go is passing the token to javascript in FB.Init, but I cannot get it to work:
FB.Init({
authResponse: {
access_token: <token>,
expiresIn: <expiry>,
signedRequest: <what-is-this?>,
userID: <user>
},
...
});
Another example I found, passed the access_token directly to the API call, but this does not seem to work either:
FB.ui({ method: 'apprequests', access_token: <token>, ... ();
Any ideas?
Let's suppose there is a website which wants to post on Facebook in the users' name. First, when the user is linked to Facebook, he will have an access token and read access so he can log in with Facebook to the website, for instance. On a given event, the user will have write access on Facebook with the access token.
After a while, the Facebook access token expires (as it seems, but if there is a way to create Facebook access tokens which will never expire I would be glad to hear about), so on the website whenever a post to Facebook is about to be made, a request has to be sent to Facebook to check the validity of the access token. If the access token is invalid, then a redirect is needed to Facebook where a new access token is generated, then Facebook redirects back to the page.
I think there are no permanent Facebook access tokens. If there are permanent Facebook access tokens, how can one create them?
If a Facebook access token expires, is there any other solution to the problem than redirecting to Facebook for access token generation and redirecting back?
EDIT:
Here: https://developers.facebook.com/docs/opengraph/howtos/publishing-with-app-token/
I have read the section with the title of "Making API Calls to Publish with an App Access Token".
It states that I need the user's FacebookID and the publish_action privilege granted by the user to be able to post in their name on Facebook. However, I am puzzled about the way I can get the user's FacebookID and how the user grants the website publish_action privilege. Also, this section mentions that
"You will be unable to retrieve information about the status update post with the given ID using the app access token. Instead, you should use a user access token for such purposes."
I do not really understand what information is impossible to be retrieved with this possibility. I do not really understand the cause of inferiority of this strategy compared to the strategy with access tokens.
The short answer is yes, you have to redirect to Facebook (or use the Javascript SDK) to get FB to give you a new access token. If the user is already logged in to Facebook and hasn't deleted your application, then the process will be mostly invisible to your user.
You can, however, extend the length of time you're allowed to use your access token from 1-2 hours to a much longer period (I can't find the time reference, but I seem to remember it being a 3-6 month period). You can read about that process in the Access Tokens Documentation.
edit
First, you have to understand the difference between an App access token and a User access token. An app access token is a very simple token that facebook uses to verify that your app is making a request that you intended it to make. Your app access token consists of your app id and your app secret as a string and separated by a | character. This token doesn't grant you access to any user information, and isn't really usable for a whole lot of things (it's basically used for the authentication methods to ensure that when you request the token, the request is coming from you and not some 3rd party masquerading as you). Though, like you found above - you can also use it to make posts to the user's feed, providing they gave you access.
A user access token identifies an actual user, and their session, to your application. The user access token typically lasts a couple of hours and then expires. You can exchange this token for an extended access token which as I stated above, I believe to last for several months.
A user token (either the temporal 1-2 hour version, or the extended version) allows you to access the FB graph API as the user to which the user belongs. So, using these tokens you can access the user's friend list, photos, likes, interests, etc (presuming you requested permission to do so upon application install). You can check which permissions you have by using the user access token and making a request to /me/permissions on the graph api.
The Javascript SDK is unique, as it doesn't require you to redirect your user away from your application. The JS SDK allows you to use a pop-up to allow the user to authenticate with facebook, install your application, or to allow (or deny) permissions that you are requesting.
The FB.login method takes 2 parameters. Parameter 1 is the callback which is executed after the user responds to your authentication prompt (either by accepting or rejecting your application install request). Parameter 2 is for options which are passed as a javascript object, the only one of which you care about here is the scope parameter. The scope parameter is the way you ask for extended permissions (such as publish_action) so in order to acquire the publish stream permission from a user you use code that looks like this
<script type="text/javascript">
FB.login(function(response)
{
//check to see if they accepted or rejected, and do something
}, { scope: "publish_action });
</script>
Once the user accepts, any subsequent calls to the FB JS SDK will automatically include your user's access token, you don't have to manage it yourself. You can make calls to the graph API on behalf of the user without having to explicitly specify the user's user id - you can just reference them as me. So, for example, you could publish to your user's feed via the JS SDK like so:
<script type="text/javascript">
FB.api('/me/feed', 'post', { message: 'test!' }, function(response)
{
//do things
});
</script>
However, if you'd rather make calls to the Graph API from your server on behalf of the user to publish to their feed (or your needs require you to do so), you'll have to store the user's FB User ID along with your user data so you can access it later. That User ID is available in the argument that is passed to the FB.login callback (response.authResponse.userID). Once you store that, you'll be able to make Graph API calls on behalf of your user from your server simply by POSTing to /<user_id>/feed with the appropriate data:
$ curl -d "message=test&access_token=<app_access_token>" /<user_id>/feed
Finally, re-authenticating your user. THE FB JS SDK exposes 3 methods for authentication.
FB.getAuthResponse
FB.getLoginStatus
FB.login
The primary difference between FB.getAuthResponse and FB.getLoginStatus is that getAuthResponse waits for a response from Facebook before any further javascript is called (it's blocking, or synchronous). FB.getLoginStatus will allow other javascript to run and will call your supplied callback when it gets a response, allowing you to do other things while you wait for a response. Either of these methods can be used to determine if your user is currently logged in to Facebook and if the user has your application installed. You can then use FB.login (if they're not logged in to FB, or not users of your app) to prompt them to login, or install, so you can access their information. Both of these methods pass you back the user's access token if they're installed and have authorized your app (response.authResponse.accessToken).
FB.login does a check for the login status of the user, but it always will pop up a login/install dialog, regardless of the status (and if they're logged in/installed, it will hide the pop-up immediately). The FB.login method is also used if you need to request additional permissions from the user (Say you just get a "vanilla" install at first, and then later the user says they want you to post to their feed. When they initiate that option, you can then request the extended permission from them). In order to utilize that functionality, you use FB.login just as you would if they were a new user, except you add the extended permissions that you want/need in the scope property of the options variable you pass as the 2nd argument.
tl;dr
Use FB.getAuthResponse or FB.getLoginStatus to determine if your user is logged in and has your application installed. These methods can also be used to fetch new access tokens as your user is using your application.
Use FB.login to get new/unauthenticated users to install your application.
Once your user logs in, fetch their user id and store it your database somewhere. This can be used to post on their behalf with your app access token once you acquire the publish_action permission from the user
If you want to store a long-lived user access token to access the user's profile and other information, later, use the link above for exchanging your user access token for an extended access token. This is a server-side process, and you can store the resulting access token in your database with the user's other credentials.
Sorry this so long and wordy - I just wanted to provide you with some solid information about access tokens, how they're used, and how to use the JS SDK to maintain them. Hope this helps.
It is suggested that whether your app uses code or token as your response_type you should perform an automated check on the access_token to confirm that the token belongs to the person the app expects it to belong to and that it was your app that generated the token.
You are supposed to do this on
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
where app-token is app_id|app_secret and token-to-inspect is the user's access_token. Also, I think from reading the documentation you can retrieve an app-token by doing a client-credentials call with the app_id and app_secret.
This is fine with an authorization flow implemented server-side, but what if you're using the implicit method and chose response_type as token (and for whatever reason aren't using FB's javascript SDK)? How do you safely get that app-token without leaking your app_secret? How does FB's SDK do it?
You can generate an app_token in your Facebook developer panel here
and then simply save it into a config file server side. From the developer's page:
App tokens do not expire and should be kept secret as they are related to your app secret.
On my page, I use the following flow:
The user authenticates with the Facebook JS SDK, and then sends his
token + uid to the server.
The server validates that the given token
is related to the given person via a call to the "debug_token"
method, that you spoke of.
If the token + uid combination is valid,
it authenticates the user server side.
I hope this helps.
We have a website where the only way to login and authenticate yourself with the site is with Facebook (this was not my choice). The first time you login with Facebook, an account gets automatically created for you.
We now want to create an iPhone application for our site and also a public API for others to use our service.
This question is about how to authenticate with our website from the app/API and is broken into 2 parts:
What is the correct way to handle REST authentication from an API to a website which only uses Facebook OAuth as an authentication method?
I have read and researched a lot about standard methods of authentication for REST API. We can't use such methods as Basic Auth over HTTPS, as there are no credentials for a user as such. Something like this seems to be only for authenticating applications using the API.
Currently, the best way I can think is you hit an /authorize end-point on our API, it redirects to Facebook OAuth, then redirects back to the site and provides a 'token' which the user of the API can use to authenticate subsequent requests.
For an official application that we create, we wouldn't necessarily need to use the public API in the same way. What would be the best way then to talk to our website and authenticate users?
I understand (I think) how to authenticate 3rd-party applications that are using our API, using API (public) keys and secret (private) keys. However, when it comes to authenticating the user who is using the app, I am getting rather confused about how to go about it when the only way we have to authenticate a user is Facebook.
I feel like I'm missing something very obvious, or don't fully understand how public REST APIs should work, so any advice and help would be greatly appreciated.
UPDATE: see below
I've been thinking hard about this question too. It's not entirely clear to me yet but here's the route I am thinking of going. I am creating a REST API an my users only auth with Facebook connect.
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
In every call to my custom API I'll include the Facebook user id and the access token.
On the API (for every method that requires user authentication):
Make a request to the /me Facebook graph using the access token from above.
Verify that the Facebook user id returned matches the user id passed to my API from above.
If the access token has expired additional communication is required.
I have yet to test this. How does it sound?
--- Update: July 27th, 2014 to answer question ---
I only use the above exchange once upon login. Once I determine which user is logging in, I create my own access token, and that token is used from that point going forward. So the new flow looks like this...
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
Request an access token from my API, including the Facebook token as a parameter
On the API
Receive access token request.
Make a request to the /me Facebook graph using the facebook access token
Verify that the Facebook user exists and match to a user in my database
Create my own access token, save it and return it to the client to be used from this point forward
This is my implementation using JWTs (JSON Web Tokens), basically similar to Chris' updated answer. I have used Facebook JS SDK and JWT.
Here's my implementation.
Client: Use Facebook JS SDK to log in and get the access token.
Client: Request JWT from my API by calling /verify-access-token endpoint.
MyAPI: Receives access token, verify it by calling /me endpoint of Facebook API.
MyAPI: If access token is valid, finds the user from database, logs in the user if exist. Create a JWT with required fields as payload, set an expiry, sign with the secret key and send back to the client.
Client: Stores the JWT in local storage.
Client: Sends the token (the JWT from step 5) along with the request for the next API call.
MyAPI: validate the token with the secret key, if token is valid, exchange the token for a new one, send it back to the client along with the API response. (No external API calls for verification of the token here after) [if the token is invalid/expired request client to authenticate again and repeat from 1]
Client Replaces the stored token with the new one and use it for the next API call. Once the token expiry is met, the token expires revoking access to API.
Every token is used once.
Read more answers about security and JWT
How secure is JWT
If you can decode JWT how are they secure?
JSON Web Tokens (JWT) as user identification and authentication tokens
I am trying to answer the same question and have been going through a lot of reading recently...
I won't have "the" answer but things are getting a little clearer for me. Have you read the comments in the article you mentioned? I found them really interesting and helpful.
As a result, and in the light of how things have evolved since the first article has been written, here's what I think I'll do:
HTTPS everywhere — this allows you to forget about HMAC, signing, nonce, ...
Use OAuth2:
When authentication requests come from my own apps/website, use this 'trick' (or a variation of it) described in a reply to the article mentioned before.
In my case, I have two types of users: those with classic login/password credentials and those who have signed up with Facebook Connect.
So I'd provide a regular login form with a "Login with Facebook" button. If the user logs in with his "classic" credentials, I'd just send these to my OAuth2 endpoint with a grant_type=password.
If he chooses to log in via Facebook, I think that would be a two-steps process:
First, use Facebook iOS SDK to open an FBSession
When that's done and the app is given back control, there should be a way to get a Facebook ID for that user. I'd send this ID alone to my OAuth2 endpoint with an extension grant understood by my server as "using an FB User ID".
Please note that I am still heavily researching on all this stuff, so that might not be a perfect answer... maybe not even a correct one! But I think that would make for a good starting point.
The idea of using an "extension grant" for the Facebook authentication might involve having to register it to do things properly? I'm not quite sure.
Anyway, I hope I was able to help you even a bit, and that at least it can start a discussion to find the best solution to this problem :)
Update
The Facebook login is not a solution as pointed in the comments: anybody could send an arbitrary user ID and log in as this user on the API.
What about doing it like this:
Show a login form with a "Facebook login" button
If this login method is chosen, act kinda like the Facebook SDK: open a web page from your authentication server, which will initiate the Facebook login.
Once the user has logged in, Facebook will use your redirect URL to confirm; make that URL point to another endpoint of your authentication server (possibly with an extra parameter indicating the call came from an app?)
When the authentication endpoint is hit, the authentication can securely identify the user, retain its FB User ID/FB Session and return an access token to your app using a custom URL scheme, just like the Facebook SDK would do
Looks better?
I receive an access token when a client allows my application on his facebook account. Based on that access token and an url I can print all his friends. I have a question: does this access token appears all the time the user logs in his application? i am asking this because the second time the user logs in in my application where i have a web browser the friend list doesn't pop up because the response from the site does not contain an access token anymore. where am i wrong? how can i check after the user accepts my app that he is online or loged in - if i want to prints his friends.
First thing: sounds like you want to add the scope offline_access because what you are trying to do is really leveraging the FB authentication mechanism.
Also: It is probably easiest to use the FB Connect button and the JavaScript Client API, unless you intend on using the graph or REST API from a back-end server.
If you ARE intending to use back-end API integration read this paragraph:
I have found it helps to ensure that you are using a proper authenticate URL (I use www.facebook.com/dialog/oauth but others have worked in the past..). Just don't use an authorize only URL, or users will be forced to grant permissions repeatedly (never really understood that 'feature'). Next redirect the user to the URL with a request token, and keep your request secret on the server side (or well encrypted if on the client side). After login, you receive the callback with an OAuth Verifier. Access verification URL graph.facebook.com/oauth/access_token with the Verifier and you will receive the OAuth Access Token. Save that token, as well as the user id.
As for checking that the current user is logged in, and/or has authorized your app and/or has friends using your app:
Have a look at FB Connect API:
http://developers.facebook.com/docs/guides/web/#login
call FB.init first, and then when you call FB.getLoginStatus, you will get an OAuth Token if the current user is logged in to FB and has previously authorized your app (either via the Connect Button or OAuth flow):
$wnd.FB.getLoginStatus(function(response) {
if (response.session)
var authToken = encodeURIComponent(response.session.access_token);
});
When executed in conjunction with the authenticate flow mentioned, users that have already authorized your application will get the same OAuth Access Token returned from previous calls, that you can use with the JS Client, Graph, or REST APIs.