Aug 232014
 

When using Omniauth’s oauth strategy for authenticating to any oauth enabled website, we often run into the problem of expired access tokens.

To refresh the access token, another call must be made to oauth2/token endpoint with the client id, client secret and the refresh token. Since this is not available out of the box in Omniauth-OAuth, I wrote some additional code in the User model file.

This call will return another JSON with a new access token and an updated expiry time. We need to save the access token and update the expiry time in our model. Keep in mind that this flow works only till the refresh token is valid. Once that expires, the entire oauth authorization workflow needs to be repeated.

This is the code I added in the user.rb model class of my rails application

def refresh_token_if_expired
  if token_expired?
    response    = RestClient.post "#{ENV['DOMAIN']}oauth2/token", :grant_type => 'refresh_token', :refresh_token => self.refresh_token, :client_id => ENV['APP_ID'], :client_secret => ENV['APP_SECRET'] 
    refreshhash = JSON.parse(response.body)
    token_will_change!
    expiresat_will_change!
    self.token     = refreshhash['access_token']
    self.expiresat = DateTime.now + refreshhash["expires_in"].to_i.seconds
    self.save
    puts 'Saved'
  end
end

def token_expired?
  expiry = Time.at(self.expiresat) 
  return true if expiry < Time.now # expired token, so we should quickly return
  token_expires_at = expiry
  save if changed?
  false # token not expired. πŸ˜€
end

The ENV[‘DOMAIN’] is the endpoint of the oauth provider. The client_id and client_secret would be provided at the time of application creation. And while making any authenticated calls, simply call this method which would check if the access token has expired already and calls the refresh method if it has.

current_user.refresh_token_if_expired
#refresh the token if it has expired

P.S: There is a dependency on rest-client gem.

P.P.S: Click here to read OAuth standards page for the refresh-token and its workflow