Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message: [AuthenticationError.OAUTH_TOKEN_HEADER_INVALID @ ; trigger:'<null>'] when using refresh token #39

Closed
huydx opened this issue Dec 4, 2014 · 10 comments

Comments

@huydx
Copy link

huydx commented Dec 4, 2014

Using the example from :
https://github.com/googleads/google-api-ads-ruby/blob/master/adwords_api/examples/v201409/misc/create_ad_words_session_without_properties_file.rb

I've got the following error:

Message: [AuthenticationError.OAUTH_TOKEN_HEADER_INVALID @ ; trigger:'<null>']
Errors:
    Error [1]:
        field_path:
        trigger: <null>
        error_string: AuthenticationError.OAUTH_TOKEN_HEADER_INVALID
        api_error_type: AuthenticationError
        reason: OAUTH_TOKEN_HEADER_INVALID
        xsi_type: ns2:AuthenticationError

However, if I'm authenticate by web and renew the access token by hand, saved to file, everything just going fine.

Can you guy trouble shoot the error.

Thank you very much.


Add:

After a while digging the code, I think the reason is that in the sample code:

  adwords = AdwordsApi::Api.new({
    :authentication => {
      :method => 'OAuth2',
      :oauth2_client_id => client_id,
      :oauth2_client_secret => client_secret,
      :developer_token => developer_token,
      :client_customer_id => client_customer_id
      :user_agent => user_agent,
      :oauth2_token => {
        :refresh_token => refresh_token
      }
    },
    :service => {
      :environment => 'PRODUCTION'
    }
  })

by setting oauth2_token => {:refresh_token => refresh_token},
it make developer think that implicit setting like this, will make the library to get access token by using refresh token.

But follow the code in ads-common :

      def get_token(credentials = nil)
        token = super(credentials)
        token = refresh_token! if !@client.nil? && @client.expired?
        return token
      end

it only using refresh token when @client nil or expired, and not check the credential.

I think the correct behaviour should be: [when refresh token present and access token not, it use refresh token to refresh access token.]

What do you maintainers think about this situation.

If it's fine, i would like to make a pull request

@huydx
Copy link
Author

huydx commented Dec 24, 2014

@dklimkin are you still working on issue #27 to add a library method to enforce the refresh. If not, i would like to make a pull request if it's possible.

@dklimkin
Copy link
Contributor

@mcloonan is currently maintaining the library. You are very welcome to send a pull request, please see:

https://github.com/googleads/google-api-ads-ruby/blob/master/adwords_api/CONTRIBUTING.md

@huydx
Copy link
Author

huydx commented Dec 24, 2014

@dklimkin @mcloonan thank you, I will send a PR ASAP.

@kobakei
Copy link

kobakei commented Sep 30, 2015

I found the same error on running https://github.com/googleads/google-api-ads-ruby/blob/master/adwords_api/examples/v201506/misc/use_runtime_config.rb with refresh token.
Any update on this issue?

@mcloonan
Copy link
Member

Thank you for the report, and I apologize that this slipped through the cracks. Since it seems @huydx may not be providing the pull request, I'll take a look at implementing a solution myself.

@jstoks
Copy link

jstoks commented Oct 1, 2015

I worked around this by providing an expires_at value in my config.

The problem is that if the OAuth2 client doesn't have that value it's never going to be considered expired and the access token won't be generated.

@Gataniel
Copy link

Gataniel commented Oct 1, 2015

@offthecuff Could you please be more specific? What is the exact place where did you provide expires_at?

@jstoks
Copy link

jstoks commented Oct 1, 2015

@Gataniel, It goes in the oauth2_token subsection of the authentication hash. Piggybacking off the example from @huydx , this is what i have:

adwords = AdwordsApi::Api.new({
    :authentication => {
      :method => 'OAuth2',
      :oauth2_client_id => client_id,
      :oauth2_client_secret => client_secret,
      :developer_token => developer_token,
      :client_customer_id => client_customer_id
      :user_agent => user_agent,
      :oauth2_token => {
        :refresh_token => refresh_token,
        :expires_at => 0
      }
    },
    :service => {
      :environment => 'PRODUCTION'
    }
  })

@jstoks
Copy link

jstoks commented Oct 1, 2015

This is the issue in a nutshell.

This method will return false if expires_at is nil.

def expired?
  return self.expires_at != nil && Time.now >= self.expires_at
end

At this point the client is not nil, but it will not be expired either so no token is created.

def get_token(credentials = nil)
  token = super(credentials)
  token = refresh_token! if !@client.nil? && @client.expired?
  return token
end

To me this honestly seems like a deficiency in the signet gem, but I suppose this might be the intended behavior.

@mcloonan
Copy link
Member

Since there's a workaround and the issue seems to be with Signet, I'm going to close this out. It might be worth filing a bug with Signet directly if this is still an issue for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants