I have deprecate_offline_access enabled for my application, and am doing some offline operations on users' pages using their access-token, which I think is supposed to be the long-lived, valid-for-60-days-unless-they-log-out variety. However, I'm seeing a lot of:
FbGraph::InvalidToken: OAuthException :: Error validating access token: Session has expired at unix time 1337922000. The current unix time is 1339090046.
And I also have seen a couple of things that indicate a need to do some extra lifting to get one of the long-lived tokens:
Does the call to FbGraph::User.access_token return one of those long-lived tokens, or is there another step?
FbGraph::User.access_token is't related to the issue.
Token lifetime is depends on which channel you used to get the token.
If you get the token via front channel, you'll get short-live token.
If it's via back channel, you'll get long-live one.
If it's front channel case, you can use FbGraph::Auth#exchange_token! to extend token expiry.
However, getting short-live in Ruby world (=basically back-channel only) smells weird from security point of view.
Can you explain how do you get the token?
(In my understanding, only APIs for mobile native apps have to handle such cases)
Sure, here's the code we use when people link their account in our app to their Facebook account:
fb_auth = FbGraph::Auth.new(FACEBOOK_APP_ID, FACEBOOK_APP_SECRET)
fb_auth.client # => Rack::OAuth2::Client
# get Facebook's auth cookie in advance using their JS SDK
@fb_user = fb_auth.user.fetch # => fetch more details
if (@fb_user && user) && (user.facebook_access_token != @fb_user.access_token.to_s)
user.update_attributes(:facebook_access_token => @fb_user.access_token.to_s, :facebook_id => @fb_user.identifier)
So we use their FB cookie and fetch their Facebook user, then store that access token and Facebook ID in our system.
Then, later, we fetch the user via that access token and use it to do things like post game scores to their page via a script that we run (we're a sports app). So we need to use the long-lived token, because the user might not be actively logged into our app when the score-posting script runs. I think that's why we're getting those token timeout errors from Facebook.
Are we getting the wrong type of token to be able to do that?
I misunderstood the case.
FbGraph::Auth#from_cookie parses the cookie, verify signature, grab authorization code in it and exchange the code with access token.
So I thought it's considered as back channel flow.
However, after debugging the flow, it returns only short-lived one, and you have to call FbGraph::Auth#exchange_token! again.
If you ask to access_token.expires_in, it'll return its life-time in seconds.
Awesome, I've put that call in and will give that a shot. And thanks for the pointer to expires_in!
One other question - is there any way to take an actual access token string and check to see if it's a short-lived or long-lived one? That would allow me to do some stats on the database to make sure the changes I've made are converting them properly.
Rats. Oh well, thanks for the clarification!