Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if token has expired

I'm trying to write a simple OAuth2 client based on oauth2 gem. The idea is to store an access token in a session and check if it's not expired before every request.

The following code for getting a new token looks like that:

client = OAuth2::Client.new(
  '26b8e5c92367d703ad35a2fc16b14dc93327a15798068ccba473aa2e3d897883',
  'b16079915cdc20b5373f1601e31cece5a84274f772cfd89aec12c90fd110775e',
  site: 'http://localhost:3000'
)

client.client_credentials.get_token.expired?

and it's working fine. Request to my api is fired and the last line shows if token has expired or not. The problem is when i'm trying to restore token state by myself:

OAuth2::AccessToken.new(client, session[:api_token]).expired?

This line of code does not fire the request to my api and, in cause of that, has no idea what's that token lifetime, expires_at param or anything else. Everything besides 'token' param is nil so expired? method always returns false:

#<OAuth2::AccessToken:0x007fad4c9e2e28 @client=#<OAuth2::Client:0x007fad4ddb7160 @id="26b8e5c92367d703ad35a2fc16b14dc93327a15798068ccba473aa2e3d897883", @secret="b16079915cdc20b5373f1601e31cece5a84274f772cfd89aec12c90fd110775e", @site="http://localhost:3000", @options={:authorize_url=>"/oauth/authorize", :token_url=>"/oauth/token", :token_method=>:post, :connection_opts=>{}, :connection_build=>nil, :max_redirects=>5, :raise_errors=>true}, @client_credentials=#<OAuth2::Strategy::ClientCredentials:0x007fad4ddb6f80 @client=#<OAuth2::Client:0x007fad4ddb7160 ...>>, @connection=#<Faraday::Connection:0x007fad4ddb6738 @headers={"User-Agent"=>"Faraday v0.8.8"}, @params={}, @options={}, @ssl={}, @parallel_manager=nil, @default_parallel_manager=nil, @builder=#<Faraday::Builder:0x007fad4ddb6620 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]>, @url_prefix=#<URI::HTTP:0x007fad4ddb60d0 URL:http://localhost:3000/>, @proxy=nil, @app=#<Faraday::Request::UrlEncoded:0x007fad4ddb4190 @app=#<Faraday::Adapter::NetHttp:0x007fad4ddb4280 @app=#<Proc:0x007fad4ddb4370@/usr/local/rvm/gems/ruby-2.0.0-p247/gems/faraday-0.8.8/lib/faraday/connection.rb:93 (lambda)>>>>>, @token="114781bdace77fa7f4629e2b42dbe68ac73326728dddc8102b9c2269e3e86a36", @refresh_token=nil, @expires_in=nil, @expires_at=nil, @options={:mode=>:header, :header_format=>"Bearer %s", :param_name=>"access_token"}, @params={}>

Am i doing something wrong or is that some kind of a bug? To sum it all up: i need to check if token stored in a session (as a string) has expired or not.

like image 318
mbajur Avatar asked Sep 18 '25 19:09

mbajur


1 Answers

If you check the code of AccessToken, you have to pass a third parameter (options) containing "expires_at" value which is used when you are calling expired? :

def initialize(client, token, opts={})
  @client = client
  @token = token.to_s
  [:refresh_token, :expires_in, :expires_at].each do |arg|
    instance_variable_set("@#{arg}", opts.delete(arg) || opts.delete(arg.to_s))
  end
  @expires_in ||= opts.delete('expires')
  @expires_in &&= @expires_in.to_i
  @expires_at &&= @expires_at.to_i
  @expires_at ||= Time.now.to_i + @expires_in if @expires_in
  @options = {:mode          => opts.delete(:mode) || :header,
              :header_format => opts.delete(:header_format) || 'Bearer %s',
              :param_name    => opts.delete(:param_name) || 'access_token'}
  @params = opts
end

...

def expired?
  expires? && (expires_at < Time.now.to_i)
end

source: https://github.com/intridea/oauth2/blob/master/lib/oauth2/access_token.rb#L42

So update your code to something like:

OAuth2::AccessToken.new(client, session[:api_token], {expires_at: session[:expires_at]}).expired?

like image 167
jeremymarc Avatar answered Sep 20 '25 08:09

jeremymarc