null refresh token (web flow) [Python]

273 views
Skip to first unread message

accforma...@gmail.com

unread,
Feb 28, 2017, 9:22:54 AM2/28/17
to AdWords API Forum
I'm trying to access adwords api on behalf of customer using this tutorial https://github.com/googleads/googleads-python-lib/wiki/API-access-on-behalf-of-your-clients-(web-flow)
I have already registered my app at google console and have my client_id, client_secret and redirect_uri.
Here is code:
flow = client.OAuth2WebServerFlow(
        client_id=g_appID,
        client_secret=g_secret,
        scope=oauth2.GetAPIScope('adwords'),
        user_agent='Pata',
code = request.args['code']
credentials = flow.step2_exchange(code)
print credentials.to_json()

oauth2_client = oauth2.GoogleRefreshTokenClient(
credentials.client_id, credentials.client_secret, credentials.refresh_token)

adwords_client = adwords.AdWordsClient(g_devToken, oauth2_client)

The problem in credentials.refresh_token - it is always null:
{"_module": "oauth2client.client", "scopes": ["https://www.googleapis.com/auth/adwords"], "token_expiry": "2017-02-28T13:48:42Z", "id_token": null, "access_token": "******some_access_token*******", "token_uri": "https://accounts.google.com/o/oauth2/token", "invalid": false, "token_response": {"access_token": "******some_access_token*******", "token_type": "Bearer", "expires_in": 3600}, "client_id": "****my_client_id****", "token_info_uri": "https://www.googleapis.com/oauth2/v2/tokeninfo", "client_secret": "****my_secret****", "revoke_uri": "https://accounts.google.com/o/oauth2/revoke", "_class": "OAuth2Credentials", "refresh_token": null, "user_agent": "Pata"}

As refresh_token is null interpreter rises error in line adwords_client = adwords.AdWordsClient(g_devToken, oauth2_client)  with folowwing error log:

File "/home/patarator/comparator/comparator.py", line 195, in get_Gtoken
2017-02-28 13:16:01,446 :    adwords_client = adwords.AdWordsClient(g_devToken, oauth2_client)
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/googleads/adwords.py", line 316, in __init__
2017-02-28 13:16:01,446 :    self.oauth2_client.Refresh()
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/googleads/oauth2.py", line 158, in Refresh
2017-02-28 13:16:01,446 :    self.proxy_config.disable_certificate_validation)))
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/oauth2client/client.py", line 633, in refresh
2017-02-28 13:16:01,446 :    self._refresh(http.request)
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/oauth2client/client.py", line 842, in _refresh
2017-02-28 13:16:01,446 :    self._do_refresh_request(http_request)
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/oauth2client/client.py", line 874, in _do_refresh_request
2017-02-28 13:16:01,446 :    self.token_uri, method='POST', body=body, headers=headers)
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/httplib2/__init__.py", line 1659, in request
2017-02-28 13:16:01,446 :    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
2017-02-28 13:16:01,446 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/httplib2/__init__.py", line 1399, in _request
2017-02-28 13:16:01,446 :    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
2017-02-28 13:16:01,447 :  File "/home/patarator/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/httplib2/__init__.py", line 1355, in _conn_request
2017-02-28 13:16:01,447 :    response = conn.getresponse()
2017-02-28 13:16:01,447 :  File "/usr/lib/python2.7/httplib.py", line 1039, in getresponse
2017-02-28 13:16:01,447 :    raise ResponseNotReady()
2017-02-28 13:16:01,447 :ResponseNotReady
I'm confused, because that code worked fine when i tested it on localhost. The only difference is redirect_uri is now ''http://patarator.pythonanywhere.com/get_Gtoken'' instead of "http://127.0.0.1:5000/get_Gtoken" ... and with localhost I used another apptype - Installed Application (there was no redirect_uri field in google console, only client_id and client_secret).

How should I correctly get that refresh_token?

accforma...@gmail.com

unread,
Feb 28, 2017, 11:18:03 AM2/28/17
to AdWords API Forum
I'm sorry, that is my fault. I have recently got that refresh token and had to revoke permission from costumer acc for my app via https://security.google.com/settings/security/permissions.
But now I facing another problem: erleier I used this code to define customer_id every time user is connected
flow = client.OAuth2WebServerFlow(
    client_id=g_appID,
    client_secret=g_secret,
    scope=oauth2.GetAPIScope('adwords'),
    user_agent='Pata',
    redirect_uri='http://127.0.0.1:5000/get_Gtoken')

code = request.args['code']
credentials = flow.step2_exchange(code)
print credentials.to_json()

oauth2_client = oauth2.GoogleRefreshTokenClient(
    credentials.client_id, credentials.client_secret, credentials.refresh_token)

# get user customer_id
adwords_client = adwords.AdWordsClient(g_devToken, oauth2_client)
customer = adwords_client.GetService('CustomerService', version='v201609').getCustomers()
customer_id = customer[0]['customerId']
In case with web app I only can receive refresh code once in order to save it and associate with customer. But there is no any customer_id or even gmail address in credentials. So, how can i get any of those when user is logged?


Shwetha Vastrad (AdWords API Team)

unread,
Feb 28, 2017, 1:52:17 PM2/28/17
to AdWords API Forum
Hi, 

Could you check if the access_type parameter is set to "offline" in your request? The refresh token is only returned if your application sets the access_type parameter to "offline" in the initial request to Google's authorization server when using Web application type credentials. Refresh tokens are always returned for installed applications, which is the reason you were receiving the refresh token when testing on localhost with an Installed application type credential. Please try this out and let me know if you are able to generate a refresh token. 

The customerId will not be returned in the response from the OAuth server when you generate a refresh token. Instead, you need to make a CustomerService.getCustomers() request like you do in the code snippet in your earlier post. 

To retrieve the email address, you need to include the scope: "https://www.googleapis.com/auth/userinfo.email" as mentioned in this document. If this scope is included while you generate the refresh token, you should be able to get the email address of the authenticating user by making the following request: 
https://www.googleapis.com/oauth2/v2/userinfo?access_token="YOUR_ACCESS_TOKEN".

You can try this out in the API explorer.

Regards,
Shwetha, AdWords API Team.

Taras Gromnitskiy

unread,
Mar 12, 2018, 4:56:37 PM3/12/18
to AdWords API Forum
Hi!

I don't getting REFRESH_TOKEN for WEB-app with access_type = "offline".

The code below:


flow = client.OAuth2WebServerFlow(
    client_id=client_id,
    client_secret=client_secret,
    scope=oauth2.GetAPIScope('adwords'),
    user_agent='Test',
    access_type="offline",
    redirect_uri="http://my_actual_site.com"
)
auth_code = 'got code here'
auth_uri = flow.step1_get_authorize_url()
credentials = flow.step2_exchange(auth_code)
credentials.to_json()

refresh_token = null

What can I do in this situation?

If I use Installed application - I work correctry.

I use this doc: https://github.com/googleads/googleads-python-lib/wiki/API-access-on-behalf-of-your-clients-(web-flow)

And Step 5 is not actually working for me.

Vincent Racaza (AdWords API Team)

unread,
Mar 13, 2018, 12:14:26 AM3/13/18
to AdWords API Forum
Hi Taras,

The link you provided is correct for the generation of OAuth2 credentials using the "web application" type. Based on the guide, the refresh token should be retrieved in Step 3 before you can use it in Step 5. Basically, the refresh token should not be null in Step 3.

Could you try the complete steps once again and check if you will receive a null value for the refresh token in Step 3? If indeed that the value is null for the refresh token, then this is more on the Python client library specific, and not AdWords API specific. I would recommend to get in touch with the library owners via this link for further assistance.

In the future, please create a new forum thread as this thread is a bit old and also, so we can better track your concern.

Thanks,
Vincent
AdWords API Team
Reply all
Reply to author
Forward
0 new messages