Posts tagged with oauth-2.0

I'm developing an integration between existing CPA system and Google AdWords. Conversions are stored in the system, and the goal is to periodically, as a background task, parse conversions and send them to user's Google Ad account.

Here's what I figured so far:

  1. I need a google application to which users will grant permission to push data to their ad account.
  2. I need Oauth2 credentials to authorize my application AND users credentials to authorize the API request.

The process of creating and storing gclid is out of concern right now.

I use php client library https://github.com/googleads/googleads-php-lib, which has adsapi_php.ini configuration file. In this file, there are developer token, manager's account client ID, and OAuth2 credentials (cliendId, clientSecret, refreshToken).

However, when user gives access to my application via consent screen, I create OAuth2 object as follows:

 $oAuth2Credential = new OAuth2([         'authorizationUri'   => 'https://accounts.google.com/o/oauth2/v2/auth',         'tokenCredentialUri' => 'https://www.googleapis.com/oauth2/v4/token',         'redirectUri'        => '<myEndpoint>',         'clientId'           => '<myClientId>',         'clientSecret'       => '<myClientSecret>',         'scope'              => 'https://www.googleapis.com/auth/adwords'     ]); 

If I understand correctly, I absolutely need to have web application OAuth credentials in order to have a callback to save user's access and refresh tokens, to use them later in my background task.

1) Does this credentials and the ones in adsapi_ini.php file has to be the same?

I've tried to generate a refresh token for my web type credentials to use in conf file, but it did not work. Right now I'm able to get a valid response when I have credentials for application type 'other' in the configuration file, and 'web' application credentials in Oauth2 object for getting user credentials, but I'm not sure this is correct way to do it.

2) How to authorize API request to push data to certain user's account?

Here's sample code:

 $session = (new AdWordsSessionBuilder())         ->fromFile()         ->withOAuth2Credential($oAuth2Credential)         ->withClientCustomerId('<client-customer-id>')         ->build(); 

As I understand, session object is essential to build any further queries, including uploding conversions.

->fromFile() uses mentined configuration file to get my token and Auth data - basically authorize my application.

$oAuth2Credential is the OAuth2 object containing specific user's authorization data. The problem is that in documentation, this object is created by builder and uses the same method fromFile(), and I don't understand what data it must contain.

I store access_token and refresh_token in my database, and right now I'm building OAuth object as follows:

$oAuth2Credential = new OAuth2([         'authorizationUri'   => 'https://accounts.google.com/o/oauth2/v2/auth',         'tokenCredentialUri' => 'https://www.googleapis.com/oauth2/v4/token',         'redirectUri'        => '<myEndpoint>',         'clientId'           => '<myClientId>',         'clientSecret'       => '<myClientSecret>',         'scope'              => 'https://www.googleapis.com/auth/adwords',         'access_token'       => '<user_access_token>'     ]); 

So basically just adding access_token to parameters that I'm using for getting this token from user. It works, but doesn't look like correct way to do this.

3) How to manage user's token expiration?

Documentation says that client library automatically handles refreshing tokens, but I don't understand how it will work in my case. Do I need to pass access_token with refresh_token in OAuth object when making API request and then it will refresh automatically, or do I need separate worker to periodically refresh user tokens to keep them valid?

I am trying to integrate Oauth2 into my Flask application, and am having some issues with keeping the flow persistent despite a redirect.

def account(): form = UpdateAccountForm() authorization_url = '' auth_code = request.args.get('code') if request.method == 'POST':     if request.form['submit_button'] == 'Test':         flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',      scopes=['https://www.googleapis.com/auth'])         flow.redirect_uri = 'http://127.0.0.1:5000/account'         authorization_url, state = flow.authorization_url(access_type='offline',                  prompt='consent', include_granted_scopes='true')         print('Please go to this URL: {}'.format(authorization_url)) if auth_code != None:     flow.fetch_token(code=auth_code)     credentials = flow.credentials     print(credentials) 

Upon button click, the Oauth flow is initiated and the user is presented with a link to a Google page in which they grant my application access to some of their features. Then, the user is redirected back to the same page but with an authorization code attached to the request which is fed back into the flow and allows me to gain access the users credentials.

This part:

if auth_code != None:     flow.fetch_token(code=auth_code)     credentials = flow.credentials     print(credentials) 

When the page reloads I get:

UnboundLocalError: local variable 'flow' referenced before assignment

I assume this happens because the flow is no longer initialized when the page loads, and obviously I can't initialize a new flow the next time the page loads because the object would be different.

I am not sure how to approach this problem within Flask, what would be the best way to keep the flow consistent?

EDIT: This question is different from the suggested duplicate because this uses Oauthlibs Flow module as opposed to the previously suggested. The closest answer is here: https://developers.google.com/identity/protocols/OAuth2WebServer but still inadequate.