When I should load a new access token? - facebook

My app uses Facebook Javascript SDK authorization on client side, and for authorized user app fetches access token from Facebook API, using facebook cookie with signed request and provided code, and store it into database.
Everything is working fine, but i'm wondering, when I should refresh stored access token? What if user have changes password, and have signed in/connected again.
As I understand, now she has new access token, and app should load it from Facebook. But how I can understand when I should check for a new token? Check on each request with facebook cookie doesn't work, because it's few request per second for each user (event if she didn't change a password). Or maybe i'm doing something wrong?
I mean:
I've authorized user on client side
I've cookie with signed request
Signed request is pretty enough to authorize user on server side (validate user credentials)
I can get access token by calling Facebook API, anytime when user user makes request to my app (because I need a code from signed request). So, i'm doing it when I don't have stored access token or existing access token has expired.
access token just stored in database, and can be used anytime, in different thread, maybe few minutes later (mean we don't have user request and cookie with signed request)
What if stored access token not expired, but invalidated on facebook side? I need to fetch new access token, but cookie has gone at this moment.
Currently I see only one way: store code from signed request into databse, and when we have found that we have invalid access token, try to load it. But i'm note sure that it's proper way, and not so much usable for most cases

You have client token and server token, the client one is short lived (a few hours) and the server one is long lived (60 days).
The token on the client side should not bother you too much since you can get a new one easily as it states in the "Handling Invalid and Expired Access Tokens" guide:
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.
The token on the server side, which you persist in the db, can not be as easily reproduced, the user has to be sent to the auth dialog again:
Desktop Web and Mobile Web apps which implement the server-side authentication flow
To obtain a fresh access token in this case you must pass the user
through the full server-side flow again: i.e. obtain a code and
exchange it for a new access token.
However, assuming the user has not de-authorized your application,
when you redirect the user into the OAuth Dialog, the user will not be
prompted to reauthorize your application, and will be immediately
redirected to your redirect_uri. This means that the re-authentication
process can appear transparent to the user.
You can of course send a client token to the server and persist that, but it's pretty pointless since it's short lived.
Another option is to use the new endpoint to extend a valid client token on the server side and then persisting that.
As for "how to know when do get a new token", on the server side when you are making api requests just check the response and see if an error returned and if so what it is (there's a list in the first url I added).
If the token has expired then just send the user to the auth dialog again (you can return some kind of code to the client side and do it from there) and then save the new token to the db.
There's no need to check cookies, those are used in the background but you should not have anything to do with them.
Edit
Don't use the cookies, they should not concern you at any time.
What you should do:
On the server side you should follow the instructions in the Server-Side auth guide, get the "code" and exchange it with a token.
That token will have 60 days.
Use that token, which you store in your db, as needed (other threads, what not) and when you are getting an error back from facebook saying that the token has expires just navigate the user back to the auth dialog page.
You can not use the "code" to get more than one token so that won't help you.
If the user session (and token) got invalidated (for various reasons) you will still get an error back from facebook when trying to make an api request, when that happens just send the user to the auth dialog again.

Related

oAuth: request token invalidates current access token

Our app already implements oAuth to obtain the access token and secret from Intuit, and all works well.
The app takes into account that users may have multiple QBO companies. Consequently, when a user tries to authorize access to one company, our app checks whether this company has been already authorized, and if it has, the app lets the user know so and does not try to re-authorize the company.
The way we implemented this is as follows. When the authorization process starts, we send or app the list of companies (realm ID) which have been authorized. The user clicks the "Connect to QuickBooks" button and follows the wizard. Internally the app gets the request token and it is ready to make the access token request. The request token request gets us the realm ID so we can compare it with the list of already authorized companies. If the company has been authorized we do not request the access token and let the user know that the company has already been authorized.
Up until a week ago this used to work -i.e. in this case, because the app does not make a request for the access token, the access token the app has is still valid. However, now something seems to have changed so that when the app makes gets the request token, even though it does not ask for the access token, the existing access token is not valid anymore and the user need to re-authorize the company again.
Has something changed in the oAuth flow implementation ?
Thanks
OAuth tokens are valid for 180 days(bydefault). So, please check if existing tokens are getting more than 180 days old. If so, please use 'reconnect api'.
Ref - https://developer.intuit.com/v2/docs/0050_quickbooks_api/0020_authentication_and_authorization/oauth_management_api#Reconnect
One suggestion -
You can implement SSO( using 'sign in with intuit' wizard) in you app. That way you can relate end-user's SSO URL with OAuth tokens of his company while persisting those in your app's db. For the very first time, end user will generate tokens through C2QB flow. Next time onwards whenever the end user will sign in, your app should retrieve his oauth tokens using his SSO identifier(your app should show 'Disconnect' option instead of C2QB if he already has an established connection).
Thanks

Facebook JS API Login guarantee of user id?

The JS API's FB.login method returns a response with a dictionary of user info, including the user id. That exists client-side in the JS api.
If this is going to be sent back to the server running the facebok canvas app, the server has to trust the user id hasn't been tampered with. As there is no signed checksum that comes back with the response, I can't see how this can be guaranteed.
I can see how you could take the user ID from the POST signed request and store that in a session, but that doesn't seem quite right. I'm sure there's a method for doing this securely that's less baroque than that.
Ideas?
You should use the Server-Side authentication for the server.
When the user loads your app and has yet to authenticate you send him to the auth dialog, when he returns you get a code which you then exchange against the facebook servers to get an access token back, you can then query the graph api for "/me" and get the user data, since you get it from the facebook servers you know it's ok.
In addition, when facebook POSTS to your canvas url you get a signed request which was signed using your app secret, after you decode it you can then check it against your secret key to verify it's authenticity.
In addition the signed request has the user id so you know that's secured as well.
I recommend using both the server side authentication and the client side one, you get different tokens (server is 60 days long, and the client is a few hours) and you can use them both.

ColdFusion Facebook Integration

I have an app with a login screen with a button that invites users to login using facebook.
That authentication part of the integration works fine. I have also parsed the returned cookie variable to obtain the userID. The next step is to obtain the users information.
I found this stackoverflow article Difficulty parsing string with Facebook one click sign on and ColdFusion which says
Once you get parsed signed_request (stored in your cookie) you can use
user_id (which is Facebook User Id) and oauth_token (aka access_token)
to get needed info via Graph API or FQL.
But, how do you obtain the access_token the poster speaks of? It is not in the cookie variable (that I can see anyway).
Sorry for being such a noob. I got twitter working easy. Facebook is a pain.
https://developers.facebook.com/docs/authentication/ is your friend. Read the server side flow section.
"If the user presses Allow, your app is authorized. The OAuth Dialog will redirect (via HTTP 302) the user's browser to the URL you passed in the redirect_uri parameter with an authorization code:
http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER
With this code in hand, you can proceed to the next step, app authentication, to gain the access token you need to make API calls.
In order to authenticate your app, you must pass the authorization code and your app secret to the Graph API token endpoint - along with the exact same redirect_uri used above - at https://graph.facebook.com/oauth/access_token. The app secret is available from the Developer App and should not be shared with anyone or embedded in any code that you will distribute (you should use the client-side flow for these scenarios).
https://graph.facebook.com/oauth/access_token?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
     client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
If your app is successfully authenticated and the authorization code from the user is valid, the authorization server will return the access token:
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission."

How to check my Facebook AccessToken? How to renew it? (.NET Desktop Application)

I've created a Facebook .NET Desktop Application. On the first run, the application opens a second window with a Web Browser directed to the authorization page for my application with the required permissions from the user.
If the user authorizes my app, Facebook is redirecting me to the static login_success.html and appends the AccessToken to the Hash (#) part of the Url of the browser rendered in my second .NET Application window.
I hand that AccessToken to my main application window and do my requests to the graph api on behalf of the respective user.
That's fine, and working so far!
But, how can I
check if the AccessToken I've stored is still valid and how
can I renew an expired AccessToken without bugging the user with the second browser window (of course assuming the user hasn't revoked the authorization for my app) and how
can I recognize that the user has revoked the authorization?
check if the AccessToken I've stored is still valid?
Try and use the token against the Graph, and if it give you an error (Something like OAuthException or OAuthError), it's not valid, else it still is.
Can I renew an expired AccessToken without bugging the user with the second browser?
No that I know of. But, AccessTokens (with the Offline Access permission) don't expire. I've received an AccessToken for one of my apps almost 2 years ago and it hasn't changed or expired, so I think you should be good. They might become invalid if your App Secret changes or if the user changes their password (I'm pretty sure on that last one, but not 100%)
Can I recognize that the user has revoked the authorization?
Yes, if you query the Graph with an AccessToken that is not authorized for that function, it will give you an OAuthException. Just check for exceptions after you receive Graph data and it will let you know, for the most part, why you weren't able to receive Facebook data.
Unfortunately, if your Access Token expires you have to get the user to go through Facebook to get a new Access Token. An offline_access token does not ever expire due to time, like joe_coolish pointed out, but it does expire if the user changes their password. So your program needs recognize when a user's access token is invalid and get the user "refresh it" by going through the oauth endpoint.
Recognizing that the user's token is invalid is the same process as recognizing that the user has revoked authorization for your application. Whenever you make a graph request with an invalid access token, Facebook will give you an OAuthException saying that you don't have access.

Facebook authentication and Ajax

I am building a Facebook application, and using the oAuth 2.0 protocol for authentication/authorization.
When a user first visits my app I am using the protocol and store the access token in order to make future requests to the Graph API. The problem occurs when the access token expires and the user is using ajax.
When the ajax request is sent I try to retrieve information from the Graph API using the access token, but since it expired I get a JSON saying the access token is invalid. Now, I can send a response back to the client saying the access token expired and on the client side I can redirect him to https://www.facebook.com/dialog/oauth to go through the authentication process again. However, since the whole process is in Ajax, redirecting the user will hurt the usability of the application.
Is there any other way I can use the protocol to get a new access token without needing to redirect the user's browser to get a new access token? Maybe something on the server side?
You just need to ask for the offline_access permission, then your access_token will not expire.
As Rafael notes, you can ask the user for offline_access and then the token should never expire. However, in practice, the access token does expire when a user changes their password or uninstalls/reinstalls your app, so you'll need to build a way for the user to reauthenticate themselves so you can update their token. I suggest redirecting them to a login page that should (ideally) just send them right back where you tell them to go without them having to do anything, and using deep linking to put them right back in your app where they left off.
I'm encountering this issue as well. One solution I came up with is as follows:
Create an async method called isAccessTokenValid()
Invoke isAccessTokenValid() before any method that will require FB interaction
If access_token has expired. save the current uri to the session, along with any form data entries (if any), and start the re-authentication process again.
Once the user has re-authenticated, bring up the stored uri.
This is a bit dirty, but I haven't seen a cleaner solution yet.