Facebook token expiration and renewal, with Koala and omniauth-facebook

Steve Bourne picture Steve Bourne · Apr 20, 2012 · Viewed 8.1k times · Source

I'm writing a Rails app that uses omniauth-facebook to authenticate the user against FB (and to get a FB OAuth access token for the user). The app then uses Koala to make various calls to the FB Graph API, using that saved OAuth token.

I update the saved token each time the user re-authenticates (typically when they log in to my app). Even so, that saved token will expire (or otherwise become invalid) from time to time.

What's the best practice around guarding against auth failures and updating the token while using Koala?

Should all calls be wrapped in begin/rescue blocks, with an exception handler that re-authenticates the user against FB?

Is there some way (using Koala) to take advantage of the 'extending access tokens' process described here? If not, are there best practices on writing my own code to extract the new token myself from a Koala call?

Answer

heavysixer picture heavysixer · May 1, 2012

What I have is a before_filter that is triggered on every page that requires an active Facebook session. Something like this should work:

  before_filter :reconnect_with_facebook
  def reconnect_with_facebook
    if current_account && current_account.token_expired?(session[:fb]["expires"])

    # re-request a token from facebook. Assume that we got a new token so
    # update it anyhow...
    session[:return_to] = request.env["REQUEST_URI"] unless request.env["REQUEST_URI"] == facebook_request_path
    redirect_to(with_canvas(facebook_request_path)) and return false
  end
end

The token_expired? method looks like this:

def token_expired?(new_time = nil)
  expiry = (new_time.nil? ? token_expires_at : Time.at(new_time))
  return true if expiry < Time.now ## expired token, so we should quickly return
  token_expires_at = expiry
  save if changed?
  false # token not expired. :D
end