Skip to content

Getting long-lived access tokens? #240

Closed
minter opened this Issue Jun 8, 2012 · 7 comments

2 participants

@minter
minter commented Jun 8, 2012

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:

http://stackoverflow.com/questions/8982025/how-to-extend-access-token-validity-since-offline-access-deprecation/9035036#9035036

Does the call to FbGraph::User.access_token return one of those long-lived tokens, or is there another step?

@nov
Owner
nov commented Jun 9, 2012

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.
https://github.com/nov/fb_graph/wiki/Authentication

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)

@nov nov closed this Jun 9, 2012
@nov nov reopened this Jun 9, 2012
@minter
minter commented Jun 9, 2012

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
    begin
      fb_auth.from_cookie(cookies)
      @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) 
      end

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?

@nov
Owner
nov commented Jun 9, 2012

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.

ps.
If you ask to access_token.expires_in, it'll return its life-time in seconds.

@minter
minter commented Jun 9, 2012

Awesome, I've put that call in and will give that a shot. And thanks for the pointer to expires_in!

@minter
minter commented Jun 9, 2012

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.

@nov
Owner
nov commented Jun 9, 2012
@minter
minter commented Jun 9, 2012

Rats. Oh well, thanks for the clarification!

@nov nov closed this Jun 13, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.