Generate User Credentials

Java

 // Copyright 2018 Google LLC 
 // 
 // Licensed under the Apache License, Version 2.0 (the "License"); 
 // you may not use this file except in compliance with the License. 
 // You may obtain a copy of the License at 
 // 
 //     http://www.apache.org/licenses/LICENSE-2.0 
 // 
 // Unless required by applicable law or agreed to in writing, software 
 // distributed under the License is distributed on an "AS IS" BASIS, 
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 // See the License for the specific language governing permissions and 
 // limitations under the License. 
 package 
  
 com.google.ads.googleads.examples.authentication 
 ; 
 import 
  
 com.beust.jcommander.Parameter 
 ; 
 import 
  
 com.google.ads.googleads.examples.utils.ArgumentNames 
 ; 
 import 
  
 com.google.ads.googleads.examples.utils.CodeSampleParams 
 ; 
 import 
  
 com.google.ads.googleads.lib.GoogleAdsClient 
 ; 
 import 
  
 com.google.ads.googleads.lib.GoogleAdsClient.Builder.ConfigPropertyKey 
 ; 
 import 
  
 com.google.api.client.http.GenericUrl 
 ; 
 import 
  
 com.google.api.client.http.HttpStatusCodes 
 ; 
 import 
  
 com.google.api.client.util.Key 
 ; 
 import 
  
 com.google.auth.oauth2.ClientId 
 ; 
 import 
  
 com.google.auth.oauth2.UserAuthorizer 
 ; 
 import 
  
 com.google.auth.oauth2.UserCredentials 
 ; 
 import 
  
 com.google.common.base.MoreObjects 
 ; 
 import 
  
 com.google.common.base.Preconditions 
 ; 
 import 
  
 com.google.common.base.Strings 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 java.io.BufferedReader 
 ; 
 import 
  
 java.io.FileInputStream 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.io.InputStreamReader 
 ; 
 import 
  
 java.io.OutputStreamWriter 
 ; 
 import 
  
 java.io.Writer 
 ; 
 import 
  
 java.math.BigInteger 
 ; 
 import 
  
 java.net.ServerSocket 
 ; 
 import 
  
 java.net.Socket 
 ; 
 import 
  
 java.net.URI 
 ; 
 import 
  
 java.nio.charset.StandardCharsets 
 ; 
 import 
  
 java.security.SecureRandom 
 ; 
 import 
  
 java.util.List 
 ; 
 import 
  
 java.util.Properties 
 ; 
 import 
  
 java.util.regex.Matcher 
 ; 
 import 
  
 java.util.regex.Pattern 
 ; 
 /** 
 * Creates an OAuth2 refresh token for the Google Ads API. This example works with both web and 
 * desktop app OAuth client ID types. 
 * 
 * <p>IMPORTANT: For web app clients types, you must add {@code http://127.0.0.1} to the "Authorized 
 * redirect URIs" list in your Google Cloud Console project before running this example. Desktop app 
 * client types do not require the local redirect to be explicitly configured in the console. 
 * 
 * <p>This example will start a basic server that listens for requests at {@code 
 * http://127.0.0.1:PORT}, where {@code PORT} is dynamically assigned. 
 */ 
 public 
  
 class 
 GenerateUserCredentials 
  
 { 
  
 private 
  
 static 
  
 class 
 GenerateUserCredentialsParams 
  
 extends 
  
 CodeSampleParams 
  
 { 
  
 @Parameter 
 ( 
  
 names 
  
 = 
  
 ArgumentNames 
 . 
 OAUTH_CLIENT_FILE 
 , 
  
 required 
  
 = 
  
 true 
 , 
  
 description 
  
 = 
  
 "JSON file downloaded from the Google Cloud Console that contains the OAuth client" 
  
 + 
  
 " details." 
 ) 
  
 private 
  
 String 
  
 oAuthClientFile 
 ; 
  
 @Parameter 
 ( 
  
 names 
  
 = 
  
 ArgumentNames 
 . 
 LOGIN_EMAIL_ADDRESS_HINT 
 , 
  
 required 
  
 = 
  
 false 
 , 
  
 description 
  
 = 
  
 "If your application knows which user is trying to authenticate, you can set this to" 
  
 + 
  
 " the user's email address so that the Google Authentication Server will" 
  
 + 
  
 " automatically populate the account selection prompt with that address." 
 ) 
  
 private 
  
 String 
  
 loginEmailAddressHint 
 ; 
  
 @Parameter 
 ( 
  
 names 
  
 = 
  
 ArgumentNames 
 . 
 OAUTH_SCOPES 
 , 
  
 required 
  
 = 
  
 false 
 , 
  
 description 
  
 = 
  
 "Scopes for the generated OAuth2 credentials. Set to the Google Ads API scope by" 
  
 + 
  
 " default, but you can add multiple scopes if you want to use the credentials for" 
  
 + 
  
 " other Google APIs." 
 ) 
  
 private 
  
 List<String> 
  
 oAuthScopes 
  
 = 
  
 SCOPES 
 ; 
  
 } 
  
 // Scopes for the generated OAuth2 credentials. The list here only contains the Google Ads API 
  
 // scope, but you can add multiple scopes if you want to use the credentials for other Google 
  
 // APIs. 
  
 private 
  
 static 
  
 final 
  
 ImmutableList<String> 
  
 SCOPES 
  
 = 
  
 ImmutableList 
 . 
< String>builder 
 (). 
 add 
 ( 
 "https://www.googleapis.com/auth/adwords" 
 ). 
 build 
 (); 
  
 private 
  
 static 
  
 final 
  
 String 
  
 OAUTH2_CALLBACK_BASE_URI 
  
 = 
  
 "http://127.0.0.1" 
 ; 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 // To fill in the values below, generate a client ID and client secret from the Google Cloud 
  
 // Console (https://console.cloud.google.com) by creating credentials for either a web or 
  
 // desktop app OAuth client ID. 
  
 // If using a web application, add the following to its "Authorized redirect URIs": 
  
 //   http://127.0.0.1 
  
 String 
  
 clientId 
 ; 
  
 String 
  
 clientSecret 
 ; 
  
 String 
  
 loginEmailAddressHint 
 ; 
  
 List<String> 
  
 scopes 
  
 = 
  
 SCOPES 
 ; 
  
 GenerateUserCredentialsParams 
  
 params 
  
 = 
  
 new 
  
 GenerateUserCredentialsParams 
 (); 
  
 if 
  
 ( 
 ! 
 params 
 . 
 parseArguments 
 ( 
 args 
 )) 
  
 { 
  
 // Either pass the required parameters for this example on the command line, or insert them 
  
 // into the code here. See the parameter class definition above for descriptions. 
  
 clientId 
  
 = 
  
 "INSERT_CLIENT_ID_HERE" 
 ; 
  
 clientSecret 
  
 = 
  
 "INSERT_CLIENT_SECRET_HERE" 
 ; 
  
 // Optional: If your application knows which user is trying to authenticate, you can set this 
  
 // to the user's email address so that the Google Authentication Server will automatically 
  
 // populate the account selection prompt with that address. 
  
 loginEmailAddressHint 
  
 = 
  
 null 
 ; 
  
 // Ensures that the client ID and client secret are not the "INSERT_..._HERE" values. 
  
 Preconditions 
 . 
 checkArgument 
 ( 
  
 ! 
 clientId 
 . 
 matches 
 ( 
 "INSERT_.*_HERE" 
 ), 
  
 "Client ID is invalid. Please update the example and try again." 
 ); 
  
 Preconditions 
 . 
 checkArgument 
 ( 
  
 ! 
 clientSecret 
 . 
 matches 
 ( 
 "INSERT_.*_HERE" 
 ), 
  
 "Client secret is invalid. Please update the example and try again." 
 ); 
  
 } 
  
 else 
  
 { 
  
 // Extracts the OAuth client information from the provided file. 
  
 ClientId 
  
 parsedClient 
  
 = 
  
 ClientId 
 . 
 fromStream 
 ( 
 new 
  
 FileInputStream 
 ( 
 params 
 . 
 oAuthClientFile 
 )); 
  
 clientId 
  
 = 
  
 parsedClient 
 . 
 getClientId 
 (); 
  
 clientSecret 
  
 = 
  
 parsedClient 
 . 
 getClientSecret 
 (); 
  
 loginEmailAddressHint 
  
 = 
  
 params 
 . 
 loginEmailAddressHint 
 ; 
  
 scopes 
  
 = 
  
 params 
 . 
 oAuthScopes 
 ; 
  
 } 
  
 new 
  
 GenerateUserCredentials 
 (). 
 runExample 
 ( 
 clientId 
 , 
  
 clientSecret 
 , 
  
 loginEmailAddressHint 
 , 
  
 scopes 
 ); 
  
 } 
  
 public 
  
 void 
  
 runExample 
 ( 
  
 String 
  
 clientId 
 , 
  
 String 
  
 clientSecret 
 , 
  
 String 
  
 loginEmailAddressHint 
 , 
  
 List<String> 
  
 scopes 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 // Creates an anti-forgery state token as described here: 
  
 // https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken 
  
 String 
  
 state 
  
 = 
  
 new 
  
 BigInteger 
 ( 
 130 
 , 
  
 new 
  
 SecureRandom 
 ()). 
 toString 
 ( 
 32 
 ); 
  
 // Creates an HTTP server that will listen for the OAuth2 callback request. 
  
 URI 
  
 baseUri 
 ; 
  
 UserAuthorizer 
  
 userAuthorizer 
 ; 
  
 AuthorizationResponse 
  
 authorizationResponse 
  
 = 
  
 null 
 ; 
  
 try 
  
 ( 
 SimpleCallbackServer 
  
 simpleCallbackServer 
  
 = 
  
 new 
  
 SimpleCallbackServer 
 ()) 
  
 { 
  
 userAuthorizer 
  
 = 
  
 UserAuthorizer 
 . 
 newBuilder 
 () 
  
 . 
 setClientId 
 ( 
 ClientId 
 . 
 of 
 ( 
 clientId 
 , 
  
 clientSecret 
 )) 
  
 . 
 setScopes 
 ( 
 scopes 
 ) 
  
 // Provides an empty callback URI so that no additional suffix is added to the 
  
 // redirect. By default, UserAuthorizer will use "/oauth2callback" if this is either 
  
 // not set or set to null. 
  
 . 
 setCallbackUri 
 ( 
 URI 
 . 
 create 
 ( 
 "" 
 )) 
  
 . 
 build 
 (); 
  
 baseUri 
  
 = 
  
 URI 
 . 
 create 
 ( 
 OAUTH2_CALLBACK_BASE_URI 
  
 + 
  
 ":" 
  
 + 
  
 simpleCallbackServer 
 . 
 getLocalPort 
 ()); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Paste this url in your browser:%n%s%n" 
 , 
  
 userAuthorizer 
 . 
 getAuthorizationUrl 
 ( 
 loginEmailAddressHint 
 , 
  
 state 
 , 
  
 baseUri 
 )); 
  
 // Waits for the authorization code. 
  
 simpleCallbackServer 
 . 
 accept 
 (); 
  
 authorizationResponse 
  
 = 
  
 simpleCallbackServer 
 . 
 authorizationResponse 
 ; 
  
 } 
  
 if 
  
 ( 
 authorizationResponse 
  
 == 
  
 null 
  
 || 
  
 authorizationResponse 
 . 
 code 
  
 == 
  
 null 
 ) 
  
 { 
  
 throw 
  
 new 
  
 NullPointerException 
 ( 
  
 "OAuth2 callback did not contain an authorization code: " 
  
 + 
  
 authorizationResponse 
 ); 
  
 } 
  
 // Confirms that the state in the response matches the state token used to generate the 
  
 // authorization URL. 
  
 if 
  
 ( 
 ! 
 state 
 . 
 equals 
 ( 
 authorizationResponse 
 . 
 state 
 )) 
  
 { 
  
 throw 
  
 new 
  
 IllegalStateException 
 ( 
 "State does not match expected state" 
 ); 
  
 } 
  
 // Exchanges the authorization code for credentials and print the refresh token. 
  
 UserCredentials 
  
 userCredentials 
  
 = 
  
 userAuthorizer 
 . 
 getCredentialsFromCode 
 ( 
 authorizationResponse 
 . 
 code 
 , 
  
 baseUri 
 ); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Your refresh token is: %s%n" 
 , 
  
 userCredentials 
 . 
 getRefreshToken 
 ()); 
  
 // Prints the configuration file contents. 
  
 Properties 
  
 adsProperties 
  
 = 
  
 new 
  
 Properties 
 (); 
  
 adsProperties 
 . 
 put 
 ( 
 ConfigPropertyKey 
 . 
 CLIENT_ID 
 . 
 getPropertyKey 
 (), 
  
 clientId 
 ); 
  
 adsProperties 
 . 
 put 
 ( 
 ConfigPropertyKey 
 . 
 CLIENT_SECRET 
 . 
 getPropertyKey 
 (), 
  
 clientSecret 
 ); 
  
 adsProperties 
 . 
 put 
 ( 
  
 ConfigPropertyKey 
 . 
 REFRESH_TOKEN 
 . 
 getPropertyKey 
 (), 
  
 userCredentials 
 . 
 getRefreshToken 
 ()); 
  
 adsProperties 
 . 
 put 
 ( 
  
 ConfigPropertyKey 
 . 
 DEVELOPER_TOKEN 
 . 
 getPropertyKey 
 (), 
  
 "INSERT_DEVELOPER_TOKEN_HERE" 
 ); 
  
 showConfigurationFile 
 ( 
 adsProperties 
 ); 
  
 } 
  
 private 
  
 void 
  
 showConfigurationFile 
 ( 
 Properties 
  
 adsProperties 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Copy the text below into a file named %s in your home directory, and replace " 
  
 + 
  
 "INSERT_XXX_HERE with your configuration:%n" 
 , 
  
 GoogleAdsClient 
 . 
 Builder 
 . 
 DEFAULT_PROPERTIES_CONFIG_FILE_NAME 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
  
 "######################## Configuration file start ########################" 
 ); 
  
 adsProperties 
 . 
 store 
 ( 
 System 
 . 
 out 
 , 
  
 null 
 ); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "# Required for manager accounts only: Specify the login customer ID used to%n" 
  
 + 
  
 "# authenticate API calls. This will be the customer ID of the authenticated%n" 
  
 + 
  
 "# manager account. You can also specify this later in code if your application%n" 
  
 + 
  
 "# uses multiple manager account + OAuth pairs.%n" 
  
 + 
  
 "#%n" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
  
 "# " 
  
 + 
  
 ConfigPropertyKey 
 . 
 LOGIN_CUSTOMER_ID 
 . 
 getPropertyKey 
 () 
  
 + 
  
 "=INSERT_LOGIN_CUSTOMER_ID" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
  
 "######################## Configuration file end ##########################" 
 ); 
  
 } 
  
 /** Basic server that listens for the OAuth2 callback. */ 
  
 private 
  
 static 
  
 class 
 SimpleCallbackServer 
  
 extends 
  
 ServerSocket 
  
 { 
  
 private 
  
 AuthorizationResponse 
  
 authorizationResponse 
 ; 
  
 SimpleCallbackServer 
 () 
  
 throws 
  
 IOException 
  
 { 
  
 // Passes a port # of zero so that a port will be automatically allocated. 
  
 super 
 ( 
 0 
 ); 
  
 } 
  
 /** 
 * Blocks until a connection is made to this server. After this method completes, the 
 * authorizationResponse of this server will be set, provided the request line is in the 
 * expected format. 
 */ 
  
 @Override 
  
 public 
  
 Socket 
  
 accept 
 () 
  
 throws 
  
 IOException 
  
 { 
  
 Socket 
  
 socket 
  
 = 
  
 super 
 . 
 accept 
 (); 
  
 try 
  
 ( 
 BufferedReader 
  
 in 
  
 = 
  
 new 
  
 BufferedReader 
 ( 
  
 new 
  
 InputStreamReader 
 ( 
 socket 
 . 
 getInputStream 
 (), 
  
 StandardCharsets 
 . 
 UTF_8 
 ))) 
  
 { 
  
 String 
  
 callbackRequest 
  
 = 
  
 in 
 . 
 readLine 
 (); 
  
 // Uses a regular expression to extract the request line from the first line of the 
  
 // callback request, e.g.: 
  
 //   GET /?code=AUTH_CODE&state=XYZ&scope=https://www.googleapis.com/auth/adwords HTTP/1.1 
  
 Pattern 
  
 pattern 
  
 = 
  
 Pattern 
 . 
 compile 
 ( 
 "GET +([^ ]+)" 
 ); 
  
 Matcher 
  
 matcher 
  
 = 
  
 pattern 
 . 
 matcher 
 ( 
 Strings 
 . 
 nullToEmpty 
 ( 
 callbackRequest 
 )); 
  
 if 
  
 ( 
 matcher 
 . 
 find 
 ()) 
  
 { 
  
 String 
  
 relativeUrl 
  
 = 
  
 matcher 
 . 
 group 
 ( 
 1 
 ); 
  
 authorizationResponse 
  
 = 
  
 new 
  
 AuthorizationResponse 
 ( 
 OAUTH2_CALLBACK_BASE_URI 
  
 + 
  
 relativeUrl 
 ); 
  
 } 
  
 try 
  
 ( 
 Writer 
  
 outputWriter 
  
 = 
  
 new 
  
 OutputStreamWriter 
 ( 
 socket 
 . 
 getOutputStream 
 ())) 
  
 { 
  
 outputWriter 
 . 
 append 
 ( 
 "HTTP/1.1 " 
 ); 
  
 outputWriter 
 . 
 append 
 ( 
 Integer 
 . 
 toString 
 ( 
 HttpStatusCodes 
 . 
 STATUS_CODE_OK 
 )); 
  
 outputWriter 
 . 
 append 
 ( 
 " OK\n" 
 ); 
  
 outputWriter 
 . 
 append 
 ( 
 "Content-Type: text/html\n\n" 
 ); 
  
 outputWriter 
 . 
 append 
 ( 
 "<b>" 
 ); 
  
 if 
  
 ( 
 authorizationResponse 
 . 
 code 
  
 != 
  
 null 
 ) 
  
 { 
  
 outputWriter 
 . 
 append 
 ( 
 "Authorization code was successfully retrieved." 
 ); 
  
 } 
  
 else 
  
 { 
  
 outputWriter 
 . 
 append 
 ( 
 "Failed to retrieve authorization code." 
 ); 
  
 } 
  
 outputWriter 
 . 
 append 
 ( 
 "</b>" 
 ); 
  
 outputWriter 
 . 
 append 
 ( 
 "<p>Please check the console output from <code>" 
 ); 
  
 outputWriter 
 . 
 append 
 ( 
 GenerateUserCredentials 
 . 
 class 
 . 
 getSimpleName 
 ()); 
  
 outputWriter 
 . 
 append 
 ( 
 "</code> for further instructions." 
 ); 
  
 } 
  
 } 
  
 return 
  
 socket 
 ; 
  
 } 
  
 } 
  
 /** Response object with attributes corresponding to OAuth2 callback parameters. */ 
  
 static 
  
 class 
 AuthorizationResponse 
  
 extends 
  
 GenericUrl 
  
 { 
  
 /** The authorization code to exchange for an access token and (optionally) a refresh token. */ 
  
 @Key 
  
 String 
  
 code 
 ; 
  
 /** Error from the request or from the processing of the request. */ 
  
 @Key 
  
 String 
  
 error 
 ; 
  
 /** State parameter from the callback request. */ 
  
 @Key 
  
 String 
  
 state 
 ; 
  
 /** 
 * Constructs a new instance based on an absolute URL. All fields annotated with the {@link Key} 
 * annotation will be set if they are present in the URL. 
 * 
 * @param encodedUrl absolute URL with query parameters. 
 */ 
  
 public 
  
 AuthorizationResponse 
 ( 
 String 
  
 encodedUrl 
 ) 
  
 { 
  
 super 
 ( 
 encodedUrl 
 ); 
  
 } 
  
 @Override 
  
 public 
  
 String 
  
 toString 
 () 
  
 { 
  
 return 
  
 MoreObjects 
 . 
 toStringHelper 
 ( 
 getClass 
 ()) 
  
 . 
 add 
 ( 
 "code" 
 , 
  
 code 
 ) 
  
 . 
 add 
 ( 
 "error" 
 , 
  
 error 
 ) 
  
 . 
 add 
 ( 
 "state" 
 , 
  
 state 
 ) 
  
 . 
 toString 
 (); 
  
 } 
  
 } 
 } 
  
  

C#

 // Copyright 2019 Google LLC 
 // 
 // Licensed under the Apache License, Version 2.0 (the "License"); 
 // you may not use this file except in compliance with the License. 
 // You may obtain a copy of the License at 
 // 
 //     http://www.apache.org/licenses/LICENSE-2.0 
 // 
 // Unless required by applicable law or agreed to in writing, software 
 // distributed under the License is distributed on an "AS IS" BASIS, 
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 // See the License for the specific language governing permissions and 
 // limitations under the License. 
 using 
  
 Google.Apis.Auth.OAuth2 
 ; 
 using 
  
 Google.Apis.Auth.OAuth2.Flows 
 ; 
 using 
  
 Google.Apis.Util.Store 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Threading 
 ; 
 using 
  
 System.Threading.Tasks 
 ; 
 namespace 
  
 Google.Ads.GoogleAds.Examples 
 { 
  
 /// <summary> 
  
 /// Entry point for the application. 
  
 /// </summary> 
  
 internal 
  
 class 
  
 Program 
  
 { 
  
 /// <summary> 
  
 /// The Google Ads API scope. 
  
 /// </summary> 
  
 private 
  
 const 
  
 string 
  
 GOOGLE_ADS_API_SCOPE 
  
 = 
  
 "https://www.googleapis.com/auth/adwords" 
 ; 
  
 /// <summary> 
  
 /// The main entry point for the application. 
  
 /// </summary> 
  
 public 
  
 static 
  
 void 
  
 Main 
 ( 
 string 
 [] 
  
 args 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "This code example creates an OAuth2 refresh token for the " 
  
 + 
  
 "Google Ads API .NET Client library. This example works with both web and " 
  
 + 
  
 "desktop app OAuth client ID types. To use this application\n" 
  
 + 
  
 "1) Follow the instructions on " 
  
 + 
  
 "https://developers.google.com/google-ads/api/docs/oauth/cloud-project " 
  
 + 
  
 "to generate a new client ID and secret.\n" 
  
 + 
  
 "2) Run this application.\n" 
  
 + 
  
 "3) Enter the client ID and client secret when prompted and follow the instructions.\n" 
  
 + 
  
 "4) Once the output is generated, copy its contents into your App.config " 
  
 + 
  
 "file. See https://developers.google.com/google-ads/api/docs/client-libs/dotnet/configuration " 
  
 + 
  
 "for other configuration options.\n\n" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "IMPORTANT: For web app clients types, you must add " 
  
 + 
  
 "'http://127.0.0.1/authorize' to the 'Authorized redirect URIs' list in your " 
  
 + 
  
 "Google Cloud Console project before running this example to avoid getting a " 
  
 + 
  
 "redirect_uri_mismatch error. Desktop app client types do not require the " 
  
 + 
  
 "local redirect to be explicitly configured in the console.\n\n" 
 ); 
  
 // Accept the client ID from user. 
  
 Console 
 . 
 Write 
 ( 
 "Enter the client ID: " 
 ); 
  
 string 
  
 clientId 
  
 = 
  
 Console 
 . 
 ReadLine 
 (); 
  
 // Accept the client ID from user. 
  
 Console 
 . 
 Write 
 ( 
 "Enter the client secret: " 
 ); 
  
 string 
  
 clientSecret 
  
 = 
  
 Console 
 . 
 ReadLine 
 (); 
  
 // Load the JSON secrets. 
  
 ClientSecrets 
  
 secrets 
  
 = 
  
 new 
  
 ClientSecrets 
 () 
  
 { 
  
 ClientId 
  
 = 
  
 clientId 
 , 
  
 ClientSecret 
  
 = 
  
 clientSecret 
  
 }; 
  
 try 
  
 { 
  
 var 
  
 initializer 
  
 = 
  
 new 
  
 GoogleAuthorizationCodeFlow 
 . 
 Initializer 
  
 { 
  
 ClientSecrets 
  
 = 
  
 secrets 
 , 
  
 Prompt 
  
 = 
  
 "consent" 
 , 
  
 }; 
  
 // Authorize the user using desktop flow. GoogleWebAuthorizationBroker creates a 
  
 // web server that listens to a random port at 127.0.0.1 and the /authorize url 
  
 // as loopback url. See https://github.com/googleapis/google-api-dotnet-client/blob/main/Src/Support/Google.Apis.Auth/OAuth2/LocalServerCodeReceiver.cs 
  
 // for details. 
  
 Task<UserCredential> 
  
 task 
  
 = 
  
 GoogleWebAuthorizationBroker 
 . 
 AuthorizeAsync 
 ( 
  
 initializer 
 , 
  
 new 
  
 string 
 [] 
  
 { 
  
 GOOGLE_ADS_API_SCOPE 
  
 }, 
  
 string 
 . 
 Empty 
 , 
  
 CancellationToken 
 . 
 None 
 , 
  
 new 
  
 NullDataStore 
 () 
  
 ); 
  
 UserCredential 
  
 credential 
  
 = 
  
 task 
 . 
 Result 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 "\nCopy the following content into your App.config file.\n\n" 
  
 + 
  
 $"<add key = 'OAuth2Mode' value = 'APPLICATION' />\n" 
  
 + 
  
 $"<add key = 'OAuth2ClientId' value = '{clientId}' />\n" 
  
 + 
  
 $"<add key = 'OAuth2ClientSecret' value = '{clientSecret}' />\n" 
  
 + 
  
 $"<add key = 'OAuth2RefreshToken' value = " 
  
 + 
  
 $"'{credential.Token.RefreshToken}' />\n" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Make sure you also set the values of LOGIN_CUSTOMER_ID header." 
  
 + 
  
 " See https://developers.google.com/google-ads/api/docs/client-libs/dotnet/configuration#google_ads_api_settings" 
  
 + 
  
 " to learn more.\n" 
  
 + 
  
 "<add key = 'LoginCustomerId' value = 'INSERT_LOGIN_CUSTOMER_ID_HERE' />" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "See https://developers.google.com/google-ads/api/docs/client-libs/dotnet/configuration " 
  
 + 
  
 "for alternate configuration options." 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "Press <Enter> to continue..." 
 ); 
  
 Console 
 . 
 ReadLine 
 (); 
  
 } 
  
 catch 
  
 ( 
 AggregateException 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "An error occurred while authorizing the user." 
 ); 
  
 } 
  
 } 
  
 } 
 } 
  
  

PHP

< ?php 
 /* 
 * Copyright 2018 Google LLC 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *     https://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */ 
 namespace Google\AdsApi\Examples\Authentication; 
 require __DIR__ . '/../../vendor/autoload.php'; 
 use Google\Auth\CredentialsLoader; 
 use Google\Auth\OAuth2; 
 use Psr\Http\Message\ServerRequestInterface; 
 use React\EventLoop\Loop; 
 use React\Http\HttpServer; 
 use React\Http\Message\Response; 
 use React\Socket\SocketServer; 
 use UnexpectedValueException; 
 /** 
 * This example will create an OAuth2 refresh token for the Google Ads API. This example works with 
 * both web and desktop app OAuth client ID types. 
 * 
 * We highly recommend running this example locally, since you won't need to generate refresh tokens 
 * very often and you can avoid issue of port settings that may occur when using a Docker container. 
 * 
 * IMPORTANT: For web app clients types, you must add "http://127.0.0.1" to the "Authorized 
 * redirect URIs" list in your Google Cloud Console project before running this example. Desktop app 
 * client types do not require the local redirect to be explicitly configured in the console. 
 * 
 * <p>This example will start a basic server that listens for requests at `http://127.0.0.1:PORT`, 
 * where `PORT` is dynamically assigned. 
 */ 
 class GenerateUserCredentials 
 { 
 /** 
 * @var string the OAuth2 scope for the Google Ads API 
 * @see https://developers.google.com/google-ads/api/docs/oauth/internals#scope 
 */ 
 private const SCOPE = 'https://www.googleapis.com/auth/adwords'; 
 /** 
 * @var string the Google OAuth2 authorization URI for OAuth2 requests 
 * @see https://developers.google.com/identity/protocols/OAuth2InstalledApp#step-2-send-a-request-to-googles-oauth-20-server 
 */ 
 private const AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/v2/auth'; 
 /** 
 * @var string the OAuth2 call back IP address. 
 */ 
 private const OAUTH2_CALLBACK_IP_ADDRESS = '127.0.0.1'; 
 public static function main() 
 { 
 if (!class_exists(HttpServer::class)) { 
 echo 'Please install "react/http" package to be able to run this example'; 
 exit(1); 
 } 
 // Creates a socket for localhost with random port. Port 0 is used to tell the SocketServer 
 // to create a server with a random port. 
 $socket = new SocketServer(self::OAUTH2_CALLBACK_IP_ADDRESS . ':0'); 
 // To fill in the values below, generate a client ID and client secret from the Google Cloud 
 // Console (https://console.cloud.google.com) by creating credentials for either a web or 
 // desktop app OAuth client ID. 
 // If using a web application, add the following to its "Authorized redirect URIs": 
 //   http://127.0.0.1 
 print 'Enter your OAuth2 client ID here: '; 
 $clientId = trim(fgets(STDIN)); 
 print 'Enter your OAuth2 client secret here: '; 
 $clientSecret = trim(fgets(STDIN)); 
 $redirectUrl = str_replace('tcp:', 'http:', $socket->getAddress()); 
 $oauth2 = new OAuth2( 
 [ 
 'clientId' => $clientId, 
 'clientSecret' => $clientSecret, 
 'authorizationUri' => self::AUTHORIZATION_URI, 
 'redirectUri' => $redirectUrl, 
 'tokenCredentialUri' => CredentialsLoader::TOKEN_CREDENTIAL_URI, 
 'scope' => self::SCOPE, 
 // Create a 'state' token to prevent request forgery. See 
 // https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken 
 // for details. 
 'state' => sha1(openssl_random_pseudo_bytes(1024)) 
 ] 
 ); 
 $authToken = null; 
 $server = new HttpServer( 
 function (ServerRequestInterface $request) use ($oauth2, &$authToken) { 
 // Stops the server after tokens are retrieved. 
 if (!is_null($authToken)) { 
 Loop::stop(); 
 } 
 // Check if the requested path is the one set as the redirect URI. We add '/' here 
 // so the parse_url method can function correctly, since it cannot detect the URI 
 // without '/' at the end, which is the case for the value of getRedirectUri(). 
 if ( 
 $request->getUri()->getPath() 
 !== parse_url($oauth2->getRedirectUri() . '/', PHP_URL_PATH) 
 ) { 
 return new Response( 
 404, 
 ['Content-Type' => 'text/plain'], 
 'Page not found' 
 ); 
 } 
 // Exit if the state is invalid to prevent request forgery. 
 $state = $request->getQueryParams()['state']; 
 if (empty($state) || ($state !== $oauth2->getState())) { 
 throw new UnexpectedValueException( 
 "The state is empty or doesn't match expected one." . PHP_EOL 
 ); 
 }; 
 // Set the authorization code and fetch refresh and access tokens. 
 $code = $request->getQueryParams()['code']; 
 $oauth2->setCode($code); 
 $authToken = $oauth2->fetchAuthToken(); 
 $refreshToken = $authToken['refresh_token']; 
 print 'Your refresh token is: ' . $refreshToken . PHP_EOL; 
 $propertiesToCopy = '[GOOGLE_ADS]' . PHP_EOL; 
 $propertiesToCopy .= 'developerToken = "INSERT_DEVELOPER_TOKEN_HERE"' . PHP_EOL; 
 $propertiesToCopy .=  <<<EOD 
 ; Required for manager accounts only: Specify the login customer ID used to authenticate API calls. 
 ; This will be the customer ID of the authenticated manager account. You can also specify this later 
 ; in code if your application uses multiple manager account + OAuth pairs. 
 ; loginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE" 
 EOD; 
 $propertiesToCopy .= PHP_EOL . '[OAUTH2]' . PHP_EOL; 
 $propertiesToCopy .= "clientId = \"{$oauth2->getClientId()}\"" . PHP_EOL; 
 $propertiesToCopy .= "clientSecret = \"{$oauth2->getClientSecret()}\"" . PHP_EOL; 
 $propertiesToCopy .= "refreshToken = \"$refreshToken\"" . PHP_EOL; 
 print 'Copy the text below into a file named "google_ads_php.ini" in your home ' 
 . 'directory, and replace "INSERT_DEVELOPER_TOKEN_HERE" with your developer ' 
 . 'token:' . PHP_EOL; 
 print PHP_EOL . $propertiesToCopy; 
 return new Response( 
 200, 
 ['Content-Type' => 'text/plain'], 
 'Your refresh token has been fetched. Check the console output for ' 
 . 'further instructions.' 
 ); 
 } 
 ); 
 $server->listen($socket); 
 printf( 
 'Log into the Google account you use for Google Ads and visit the following URL ' 
 . 'in your web browser: %1$s%2$s%1$s%1$s', 
 PHP_EOL, 
 $oauth2->buildFullAuthorizationUri(['access_type' => 'offline']) 
 ); 
 } 
 } 
 GenerateUserCredentials::main(); 
  
  

Python

 #!/usr/bin/env python 
 # Copyright 2018 Google LLC 
 from 
  
 typing 
  
 import 
 List 
 , 
 Dict 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #     https://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 """This example will create an OAuth2 refresh token for the Google Ads API. 
 This example works with both web and desktop app OAuth client ID types. 
 https://console.cloud.google.com 
 IMPORTANT: For web app clients types, you must add "http://127.0.0.1" to the 
 "Authorized redirect URIs" list in your Google Cloud Console project before 
 running this example. Desktop app client types do not require the local 
 redirect to be explicitly configured in the console. 
 Once complete, download the credentials and save the file path so it can be 
 passed into this example. 
 This example is a very simple implementation, for a more detailed example see: 
 https://developers.google.com/identity/protocols/oauth2/web-server#python 
 """ 
 import 
  
 argparse 
 import 
  
 hashlib 
 import 
  
 os 
 import 
  
 re 
 import 
  
 socket 
 import 
  
 sys 
 from 
  
 urllib.parse 
  
 import 
 unquote 
 # If using Web flow, the redirect URL must match exactly what’s configured in GCP for 
 # the OAuth client.  If using Desktop flow, the redirect must be a localhost URL and 
 # is not explicitly set in GCP. 
 from 
  
 google_auth_oauthlib.flow 
  
 import 
 Flow 
 _SCOPE 
 = 
 "https://www.googleapis.com/auth/adwords" 
 _SERVER 
 = 
 "127.0.0.1" 
 _PORT 
 = 
 8080 
 _REDIRECT_URI 
 = 
 f 
 "http:// 
 { 
 _SERVER 
 } 
 : 
 { 
 _PORT 
 } 
 " 
 def 
  
 main 
 ( 
 client_secrets_path 
 : 
 str 
 , 
 scopes 
 : 
 List 
 [ 
 str 
 ]) 
 - 
> None 
 : 
  
 """The main method, starts a basic server and initializes an auth request. 
 Args: 
 client_secrets_path: a path to where the client secrets JSON file is 
 located on the machine running this example. 
 scopes: a list of API scopes to include in the auth request, see: 
 https://developers.google.com/identity/protocols/oauth2/scopes 
 """ 
 flow 
 = 
 Flow 
 . 
 from_client_secrets_file 
 ( 
 client_secrets_path 
 , 
 scopes 
 = 
 scopes 
 ) 
 flow 
 . 
 redirect_uri 
 = 
 _REDIRECT_URI 
 # Create an anti-forgery state token as described here: 
 # https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken 
 passthrough_val 
 = 
 hashlib 
 . 
 sha256 
 ( 
 os 
 . 
 urandom 
 ( 
 1024 
 )) 
 . 
 hexdigest 
 () 
 authorization_url 
 , 
 state 
 = 
 flow 
 . 
 authorization_url 
 ( 
 access_type 
 = 
 "offline" 
 , 
 state 
 = 
 passthrough_val 
 , 
 prompt 
 = 
 "consent" 
 , 
 include_granted_scopes 
 = 
 "true" 
 , 
 ) 
 # Prints the authorization URL so you can paste into your browser. In a 
 # typical web application you would redirect the user to this URL, and they 
 # would be redirected back to "redirect_url" provided earlier after 
 # granting permission. 
 print 
 ( 
 "Paste this URL into your browser: " 
 ) 
 print 
 ( 
 authorization_url 
 ) 
 print 
 ( 
 f 
 " 
 \n 
 Waiting for authorization and callback to: 
 { 
 _REDIRECT_URI 
 } 
 " 
 ) 
 # Retrieves an authorization code by opening a socket to receive the 
 # redirect request and parsing the query parameters set in the URL. 
 code 
 = 
 unquote 
 ( 
 get_authorization_code 
 ( 
 passthrough_val 
 )) 
 # Pass the code back into the OAuth module to get a refresh token. 
 flow 
 . 
 fetch_token 
 ( 
 code 
 = 
 code 
 ) 
 refresh_token 
 = 
 flow 
 . 
 credentials 
 . 
 refresh_token 
 print 
 ( 
 f 
 " 
 \n 
 Your refresh token is: 
 { 
 refresh_token 
 } 
 \n 
 " 
 ) 
 print 
 ( 
 "Add your refresh token to your client library configuration as " 
 "described here: " 
 "https://developers.google.com/google-ads/api/docs/client-libs/python/configuration" 
 ) 
 def 
  
 get_authorization_code 
 ( 
 passthrough_val 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Opens a socket to handle a single HTTP request containing auth tokens. 
 Args: 
 passthrough_val: an anti-forgery token used to verify the request 
 received by the socket. 
 Returns: 
 a str access token from the Google Auth service. 
 """ 
 # Open a socket at _SERVER:_PORT and listen for a request 
 sock 
 = 
 socket 
 . 
 socket 
 () 
 sock 
 . 
 setsockopt 
 ( 
 socket 
 . 
 SOL_SOCKET 
 , 
 socket 
 . 
 SO_REUSEADDR 
 , 
 1 
 ) 
 sock 
 . 
 bind 
 (( 
 _SERVER 
 , 
 _PORT 
 )) 
 sock 
 . 
 listen 
 ( 
 1 
 ) 
 connection 
 , 
 address 
 = 
 sock 
 . 
 accept 
 () 
 data 
 = 
 connection 
 . 
 recv 
 ( 
 1024 
 ) 
 # Parse the raw request to retrieve the URL query parameters. 
 params 
 = 
 parse_raw_query_params 
 ( 
 data 
 ) 
 try 
 : 
 if 
 not 
 params 
 . 
 get 
 ( 
 "code" 
 ): 
 # If no code is present in the query params then there will be an 
 # error message with more details. 
 error 
 = 
 params 
 . 
 get 
 ( 
 "error" 
 ) 
 message 
 = 
 f 
 "Failed to retrieve authorization code. Error: 
 { 
 error 
 } 
 " 
 raise 
 ValueError 
 ( 
 message 
 ) 
 elif 
 params 
 . 
 get 
 ( 
 "state" 
 ) 
 != 
 passthrough_val 
 : 
 message 
 = 
 "State token does not match the expected state." 
 raise 
 ValueError 
 ( 
 message 
 ) 
 else 
 : 
 message 
 = 
 "Authorization code was successfully retrieved." 
 except 
 ValueError 
 as 
 error 
 : 
 print 
 ( 
 error 
 ) 
 sys 
 . 
 exit 
 ( 
 1 
 ) 
 finally 
 : 
 response 
 = 
 ( 
 "HTTP/1.1 200 OK 
 \n 
 " 
 "Content-Type: text/html 
 \n\n 
 " 
 f 
 "<b> 
 { 
 message 
 } 
< /b>" 
 "<p>Please check the console output.</p> 
 \n 
 " 
 ) 
 connection 
 . 
 sendall 
 ( 
 response 
 . 
 encode 
 ()) 
 connection 
 . 
 close 
 () 
 return 
 params 
 . 
 get 
 ( 
 "code" 
 ) 
 def 
  
 parse_raw_query_params 
 ( 
 data 
 : 
 bytes 
 ) 
 - 
> Dict 
 [ 
 str 
 , 
 str 
 ]: 
  
 """Parses a raw HTTP request to extract its query params as a dict. 
 Note that this logic is likely irrelevant if you're building OAuth logic 
 into a complete web application, where response parsing is handled by a 
 framework. 
 Args: 
 data: raw request data as bytes. 
 Returns: 
 a dict of query parameter key value pairs. 
 """ 
 # Decode the request into a utf-8 encoded string 
 decoded 
 = 
 data 
 . 
 decode 
 ( 
 "utf-8" 
 ) 
 # Use a regular expression to extract the URL query parameters string 
 match 
 = 
 re 
 . 
 search 
 ( 
 r 
 "GET\s\/\?(.*) " 
 , 
 decoded 
 ) 
 params 
 = 
 match 
 . 
 group 
 ( 
 1 
 ) 
 # Split the parameters to isolate the key/value pairs 
 pairs 
 = 
 [ 
 pair 
 . 
 split 
 ( 
 "=" 
 ) 
 for 
 pair 
 in 
 params 
 . 
 split 
 ( 
 "&" 
 )] 
 # Convert pairs to a dict to make it easy to access the values 
 return 
 { 
 key 
 : 
 val 
 for 
 key 
 , 
 val 
 in 
 pairs 
 } 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 parser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "Generates OAuth2 refresh token using the Web application flow. " 
 "To retrieve the necessary client_secrets JSON file, first " 
 "generate OAuth 2.0 credentials of type Web application in the " 
 "Google Cloud Console (https://console.cloud.google.com). " 
 "Make sure 'http://_SERVER:_PORT' is included the list of " 
 "'Authorized redirect URIs' for this client ID." 
 ), 
 ) 
 # The following argument(s) should be provided to run the example. 
 parser 
 . 
 add_argument 
 ( 
 "-c" 
 , 
 "--client_secrets_path" 
 , 
 required 
 = 
 True 
 , 
 type 
 = 
 str 
 , 
 help 
 = 
 ( 
 "Path to the client secrets JSON file from the Google Developers " 
 "Console that contains your client ID, client secret, and " 
 "redirect URIs." 
 ), 
 ) 
 parser 
 . 
 add_argument 
 ( 
 "--additional_scopes" 
 , 
 default 
 = 
 None 
 , 
 type 
 = 
 str 
 , 
 nargs 
 = 
 "+" 
 , 
 help 
 = 
 "Additional scopes to apply when generating the refresh token." 
 , 
 ) 
 args 
 = 
 parser 
 . 
 parse_args 
 () 
 configured_scopes 
 = 
 [ 
 _SCOPE 
 ] 
 if 
 args 
 . 
 additional_scopes 
 : 
 configured_scopes 
 . 
 extend 
 ( 
 args 
 . 
 additional_scopes 
 ) 
 main 
 ( 
 args 
 . 
 client_secrets_path 
 , 
 configured_scopes 
 ) 
  

Ruby

 #!/usr/bin/env ruby 
 # Encoding: utf-8 
 # 
 # Copyright 2018 Google LLC 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #     https://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 # 
 # This example will create an OAuth2 refresh token for the Google Ads API using 
 # the Web application flow. 
 # 
 # This example will start a basic server that listens for requests at 
 # http://localhost:PORT, where PORT is the port specified below. 
 require 
  
 'googleauth' 
 require 
  
 'securerandom' 
 require 
  
 'uri' 
 require 
  
 'cgi' 
 require 
  
 'socket' 
 require 
  
 'json' 
 require 
  
 'optparse' 
 def 
  
 generate_user_credential 
 ( 
 path 
 ) 
  
 json 
  
 = 
  
 JSON 
 . 
 load_file 
 ( 
 path 
 ) 
  
 creds 
 , 
  
 callback_uri 
 , 
  
 port 
  
 = 
  
 if 
  
 ! 
 json 
 [ 
 "installed" 
 ]. 
 nil? 
  
 [ 
 json 
 [ 
 "installed" 
 ] 
 , 
  
 "http:// 
 #{ 
 SERVER 
 } 
 : 
 #{ 
 PORT 
 } 
 " 
 , 
  
 PORT 
 ] 
  
 elsif 
  
 ! 
 json 
 [ 
 "web" 
 ]. 
 nil? 
  
 web_creds 
  
 = 
  
 json 
 [ 
 "web" 
 ] 
  
 # If you have more than one redirect URI, you may need to add some 
  
 # code here to ensure that you choose the correct one. 
  
 uri 
  
 = 
  
 json 
 [ 
 "web" 
 ][ 
 "redirect_uris" 
 ]. 
 first 
  
 port 
  
 = 
  
 uri 
 . 
 split 
 ( 
 ":" 
 ) 
 . 
 last 
  
 [ 
 web_creds 
 , 
  
 uri 
 , 
  
 port 
 ] 
  
 else 
  
 raise 
  
 "No installed or web credentials found." 
  
 end 
  
 # Create an anti-forgery state token as described here: 
  
 # https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken 
  
 state 
  
 = 
  
 SecureRandom 
 . 
 hex 
 ( 
 16 
 ) 
  
 client_id 
  
 = 
  
 Google 
 :: 
 Auth 
 :: 
 ClientId 
 . 
 new 
 ( 
  
 creds 
 [ 
 "client_id" 
 ] 
 , 
  
 creds 
 [ 
 "client_secret" 
 ] 
 , 
  
 ) 
  
 # This example does not store credentials, so no TokenStore is needed. 
  
 user_authorizer 
  
 = 
  
 Google 
 :: 
 Auth 
 :: 
 UserAuthorizer 
 . 
 new 
 ( 
  
 client_id 
 , 
  
 SCOPE 
 , 
  
 nil 
 , 
  
 callback_uri 
 ) 
  
 authorization_url 
  
 = 
  
 user_authorizer 
 . 
 get_authorization_url 
 ( 
 state 
 : 
  
 state 
 ) 
  
 printf 
 ( 
 "Paste this url in your browser: 
 \n 
 %s 
 \n 
 " 
 , 
  
 authorization_url 
 ) 
  
 printf 
 ( 
 "Waiting for authorization and callback... 
 \n 
 " 
 ) 
  
 printf 
 ( 
 "Listening at %s 
 \n 
 " 
 , 
  
 callback_uri 
 ) 
  
 response_params 
  
 = 
  
 get_authorization_code 
 ( 
 port 
 ) 
  
 # Confirm that the state in the response matches the state token used to 
  
 # generate the authorization URL. 
  
 unless 
  
 state 
  
 == 
  
 response_params 
 [ 
 'state' 
 ][ 
 0 
 ] 
  
 raise 
  
 StandardError 
 , 
  
 'State returned from callback does not match the expected state' 
  
 end 
  
 user_credentials 
  
 = 
  
 user_authorizer 
 . 
 get_credentials_from_code 
 ( 
  
 code 
 : 
  
 response_params 
 [ 
 'code' 
 ][ 
 0 
 ] 
 ) 
  
 printf 
 ( 
 "Your refresh token is: %s 
 \n 
 " 
 , 
  
 user_credentials 
 . 
 refresh_token 
 ) 
  
 printf 
 ( 
 "Copy your refresh token above into your google_ads_config.rb in your " 
 \ 
  
 "home directory or use it when instantiating the library. 
 \n 
 " 
 ) 
 end 
 def 
  
 get_authorization_code 
 ( 
 port 
 ) 
  
 authorization_code 
  
 = 
  
 nil 
  
 server 
  
 = 
  
 TCPServer 
 . 
 open 
 ( 
 port 
 ) 
  
 client 
  
 = 
  
 server 
 . 
 accept 
  
 callback_request 
  
 = 
  
 client 
 . 
 readline 
  
 # Use a regular expression to extract the request line from the first line of 
  
 # the callback request, e.g.: 
  
 #   GET /?code=AUTH_CODE&state=XYZ&scope=... HTTP/1.1 
  
 matcher 
  
 = 
 /GET +([^ ]+)/ 
 . 
 match 
 ( 
 callback_request 
 ) 
  
 response_params 
  
 = 
  
 CGI 
 . 
 parse 
 ( 
 URI 
 . 
 parse 
 ( 
 matcher 
 [ 
 1 
 ] 
 ) 
 . 
 query 
 ) 
  
 unless 
  
 matcher 
 . 
 nil? 
  
 client 
 . 
 puts 
 ( 
 "HTTP/1.1 200 OK" 
 ) 
  
 client 
 . 
 puts 
 ( 
 "Content-Type: text/html" 
 ) 
  
 client 
 . 
 puts 
 ( 
 "" 
 ) 
  
 client 
 . 
 puts 
 ( 
 "<b>" 
 ) 
  
 if 
  
 response_params 
 [ 
 'code' 
 ]. 
 nil? 
  
 client 
 . 
 puts 
 ( 
 "Failed to retrieve authorization code." 
 ) 
  
 else 
  
 client 
 . 
 puts 
 ( 
 "Authorization code was successfully retrieved." 
 ) 
  
 end 
  
 client 
 . 
 puts 
 ( 
 "</b>" 
 ) 
  
 client 
 . 
 puts 
 ( 
 "<p>Please check the console output.</p>" 
 ) 
  
 client 
 . 
 close 
  
 return 
  
 response_params 
 end 
 if 
  
 __FILE__ 
  
 == 
  
 $PROGRAM_NAME 
  
 SCOPE 
  
 = 
  
 'https://www.googleapis.com/auth/adwords' 
  
 SERVER 
  
 = 
  
 '127.0.0.1' 
  
 PORT 
  
 = 
  
 8080 
  
 # To fill in the values below, generate a client secret JSON file from the 
  
 # Google Cloud Console (https://console.cloud.google.com) by creating 
  
 # credentials for a web or desktop application. If using a web application, 
  
 # add the following to its "Authorized redirect URIs": 
  
 # http://127.0.0.1:[PORT] 
  
 options 
  
 = 
  
 {} 
  
 # The following parameter(s) should be provided to run the example. You can 
  
 # either specify these by changing the INSERT_XXX_ID_HERE values below, or on 
  
 # the command line. 
  
 # 
  
 # Parameters passed on the command line will override any parameters set in 
  
 # code. 
  
 # 
  
 # Running the example with -h will print the command line usage. 
  
 options 
 [ 
 :path 
 ] 
  
 = 
  
 'INSERT_CLIENT_SECRETS_PATH_HERE' 
  
 OptionParser 
 . 
 new 
  
 do 
  
 | 
 opts 
 | 
  
 opts 
 . 
 banner 
  
 = 
  
 sprintf 
 ( 
 'Usage: %s [options]' 
 , 
  
 File 
 . 
 basename 
 ( 
 __FILE__ 
 )) 
  
 opts 
 . 
 separator 
  
 '' 
  
 opts 
 . 
 separator 
  
 'Options:' 
  
 opts 
 . 
 on 
 ( 
 '-P' 
 , 
  
 '--client-secrets-path CLIENT-SECRETS-PATH' 
 , 
  
 String 
 , 
  
 'Client Secrets Path' 
 ) 
  
 do 
  
 | 
 v 
 | 
  
 options 
 [ 
 :path 
 ] 
  
 = 
  
 v 
  
 end 
  
 opts 
 . 
 separator 
  
 '' 
  
 opts 
 . 
 separator 
  
 'Help:' 
  
 opts 
 . 
 on_tail 
 ( 
 '-h' 
 , 
  
 '--help' 
 , 
  
 'Show this message' 
 ) 
  
 do 
  
 puts 
  
 opts 
  
 exit 
  
 end 
  
 end 
 . 
 parse! 
  
 generate_user_credential 
 ( 
  
 options 
 [ 
 :path 
 ] 
 , 
  
 ) 
 end 
  
  

Perl

 #!/usr/bin/perl -w 
 # 
 # Copyright 2019, Google LLC 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #     http://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 # 
 # This example will create an OAuth2 refresh token for the Google Ads API. 
 # This works with both web and desktop app OAuth client ID types. 
 # 
 # This example will start a basic server that listens for requests at 
 # http://127.0.0.1:PORT, where PORT defaults to 8080 as below. 
 # 
 # 
 # [IMPORTANT]: For web app client types, you must add http://127.0.0.1 to the 
 # "Authorize redirect URIs" list in your Google Cloud Console project before 
 # running this example. Desktop app client types do not require the local 
 # redirect to be explicitly configured in the console. 
 use 
  
 strict 
 ; 
 use 
  
 warnings 
 ; 
 use 
  
 utf8 
 ; 
 use 
  
 FindBin 
  
 qw($Bin) 
 ; 
 use 
  
 lib 
  
 "$Bin/../../lib" 
 ; 
 use 
  
 Google::Ads::GoogleAds::Client 
 ; 
 use 
  
 Google::Ads::GoogleAds::Utils::GoogleAdsHelper 
 ; 
 use 
  
 Getopt::Long 
  
 qw(:config auto_help) 
 ; 
 use 
  
 Pod::Usage 
 ; 
 use 
  
 Cwd 
  
 qw(abs_path) 
 ; 
 use 
  
 Data::Uniqid 
  
 qw(uniqid) 
 ; 
 use 
  
 Digest::SHA 
  
 qw(sha1_hex) 
 ; 
 use 
  
 constant 
  
 OAUTH2_CALLBACK_BASE_URI 
  
 = 
>  
 "http://127.0.0.1" 
 ; 
 use 
  
 constant 
  
 PORT 
  
 = 
>  
 8080 
 ; 
 # The following parameter(s) should be provided to run the example. You can 
 # either specify these by changing the INSERT_XXX_ID_HERE values below, or on 
 # the command line. 
 # 
 # Parameters passed on the command line will override any parameters set in 
 # code. 
 # 
 # Running the example with -h will print the command line usage. 
 my 
  
 $client_id 
  
 = 
  
 "INSERT_CLIENT_ID_HERE" 
 ; 
 my 
  
 $client_secret 
  
 = 
  
 "INSERT_CLIENT_SECRET_HERE" 
 ; 
 my 
  
 $additional_scopes 
  
 = 
  
 "INSERT_ADDITIONAL_SCOPES_HERE" 
 ; 
 # Create an anti-forgery state token as described here: 
 # https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken 
 our 
  
 $state 
  
 = 
  
 sha1_hex 
 ( 
 uniqid 
 ); 
 sub 
  
 generate_user_credentials 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $client_id 
 , 
  
 $client_secret 
 , 
  
 $additional_scopes 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $auth_handler 
  
 = 
  
 $api_client 
 - 
> get_oauth2_handler 
 (); 
  
 my 
  
 $callback_url 
  
 = 
  
 sprintf 
 ( 
 "%s:%d" 
 , 
  
 OAUTH2_CALLBACK_BASE_URI 
 , 
  
 PORT 
 ); 
  
 $auth_handler 
 - 
> set_client_id 
 ( 
 $client_id 
 ); 
  
 $auth_handler 
 - 
> set_client_secret 
 ( 
 $client_secret 
 ); 
  
 $auth_handler 
 - 
> set_redirect_uri 
 ( 
 $callback_url 
 ); 
  
 $auth_handler 
 - 
> set_additional_scopes 
 ( 
 $additional_scopes 
 ) 
  
 if 
  
 check_params 
 ( 
 $additional_scopes 
 ); 
  
 # Open a browser and point it to the authorization URL, authorize the access. 
  
 print 
  
 "\nPaste this url in your browser:\n" 
 , 
  
 $auth_handler 
 - 
> get_authorization_url 
 ( 
 $state 
 ), 
  
 "\n\n" 
 ; 
  
 printf 
  
 "Waiting for authorization and callback to %s ...\n" 
 , 
  
 $callback_url 
 ; 
  
 SimpleCallbackServer 
 - 
> new 
 ( 
 PORT 
 , 
  
 $auth_handler 
 ) 
 - 
> run 
 ; 
  
 return 
  
 1 
 ; 
 } 
 { 
  
 # Simple CGI server that listens for the OAuth2 callback. 
  
 package 
  
 SimpleCallbackServer 
 ; 
  
 use 
  
 HTTP::Server::Simple::CGI 
 ; 
  
 use 
  
 base 
  
 qw(HTTP::Server::Simple::CGI) 
 ; 
  
 sub 
  
 new 
  
 { 
  
 my 
  
 ( 
 $class 
 , 
  
 $port 
 , 
  
 $auth_handler 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $self 
  
 = 
  
 HTTP::Server::Simple:: 
 CGI 
 - 
> new 
 ( 
 $port 
 ); 
  
 $self 
 - 
> { 
 auth_handler 
 } 
  
 = 
  
 $auth_handler 
 ; 
  
 bless 
  
 $self 
 , 
  
 $class 
 ; 
  
 return 
  
 $self 
 ; 
  
 } 
  
 my 
  
 %dispatch 
  
 = 
  
 ( 
 '/' 
  
 = 
>  
 \ 
& resp_callback 
 ); 
  
 sub 
  
 handle_request 
  
 { 
  
 my 
  
 ( 
 $self 
 , 
  
 $cgi 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $path 
  
 = 
  
 $cgi 
 - 
> path_info 
 ; 
  
 my 
  
 $handler 
  
 = 
  
 $dispatch 
 { 
 $path 
 }; 
  
 if 
  
 ( 
 ref 
 ( 
 $handler 
 ) 
  
 eq 
  
 "CODE" 
 ) 
  
 { 
  
 print 
  
 "HTTP/1.0 200 OK\r\n" 
 ; 
  
 $handler 
 - 
> ( 
 $self 
 , 
  
 $cgi 
 ); 
  
 } 
  
 else 
  
 { 
  
 print 
  
 "HTTP/1.0 404 Not found\r\n" 
 ; 
  
 print 
  
 $cgi 
 - 
> header 
 , 
  
 $cgi 
 - 
> start_html 
 ( 
 'Not found' 
 ), 
  
 $cgi 
 - 
> h1 
 ( 
 'Not found' 
 ), 
  
 $cgi 
 - 
> end_html 
 ; 
  
 } 
  
 } 
  
 # The method to handle the callback request after user logs in and accepts 
  
 # the OAuth2 prompt. An authorization code will be returned which can be 
  
 # exchanged for an access token and refresh token. 
  
 sub 
  
 resp_callback 
  
 { 
  
 my 
  
 ( 
 $self 
 , 
  
 $cgi 
 ) 
  
 = 
  
 @_ 
 ; 
  
 return 
  
 if 
  
 ! 
 ref 
  
 $cgi 
 ; 
  
 # Get the authorization code and state parameters from the URL. 
  
 my 
  
 $code 
  
 = 
  
 $cgi 
 - 
> param 
 ( 
 'code' 
 ); 
  
 my 
  
 $state 
  
 = 
  
 $cgi 
 - 
> param 
 ( 
 'state' 
 ); 
  
 if 
  
 ( 
 ! 
 $code 
 ) 
  
 { 
  
 print 
  
 "\r\n<b>Failed to retrieve the authorization code.<b>" 
 ; 
  
 } 
  
 elsif 
  
 ( 
 $state 
  
 ne 
  
 $ 
 main:: 
 state 
 ) 
  
 { 
  
 # Confirm that the state in the response matches the state token used to 
  
 # generate the authorization URL. 
  
 print 
  
 "\r\n<b>State in the callback does not match the expected value.<b>" 
 ; 
  
 } 
  
 else 
  
 { 
  
 my 
  
 $auth_handler 
  
 = 
  
 $self 
 - 
> { 
 auth_handler 
 }; 
  
 $auth_handler 
 - 
> issue_access_token 
 ( 
 $code 
 ); 
  
 # After the access token and refresh token are generated, you should store the 
  
 # refresh token and reuse it for future calls, by either changing your 
  
 # googleads.properties file or setting in the authorization handler as follows: 
  
 # 
  
 # $api_client->get_oauth2_handler()->set_client_id($client_id); 
  
 # $api_client->get_oauth2_handler()->set_client_secret($client_secret); 
  
 # $api_client->get_oauth2_handler()->set_refresh_token($refresh_token); 
  
 print 
  
 "\r\n<b>Authorization code was successfully retrieved.</b>" 
 ; 
  
 print 
  
 "<p><b>Replace the following keys and values in your " 
  
 . 
  
 "googleads.properties configuration file:</b><p>" 
 ; 
  
 printf 
 ( 
  
 "clientId=%s<br>clientSecret=%s<br>refreshToken=%s<br>" 
 , 
  
 $auth_handler 
 - 
> get_client_id 
 , 
  
 $auth_handler 
 - 
> get_client_secret 
 , 
  
 $auth_handler 
 - 
> get_refresh_token 
  
 ); 
  
 print 
  
 STDERR 
  
 "Press Ctrl+C to quit.\n" 
 ; 
  
 } 
  
 } 
 } 
 # Don't run the example if the file is being included. 
 if 
  
 ( 
 abs_path 
 ( 
 $0 
 ) 
  
 ne 
  
 abs_path 
 ( 
 __FILE__ 
 )) 
  
 { 
  
 return 
  
 1 
 ; 
 } 
 # Get Google Ads Client with the default API version. 
 my 
  
 $api_client 
  
 = 
  
 Google::Ads::GoogleAds:: 
 Client 
 - 
> new 
 (); 
 # Parameters passed on the command line will override any parameters set in code. 
 GetOptions 
 ( 
  
 'client_id=s' 
  
 = 
>  
 \ 
 $client_id 
 , 
  
 'client_secret=s' 
  
 = 
>  
 \ 
 $client_secret 
 , 
  
 'additional_scopes=s' 
  
 = 
>  
 \ 
 $additional_scopes 
 ); 
 # Print the help message if the parameters are not initialized in the code nor 
 # in the command line. 
 pod2usage 
 ( 
 2 
 ) 
  
 if 
  
 not 
  
 check_params 
 ( 
 $client_id 
 , 
  
 $client_secret 
 ); 
 # Call the example. 
 generate_user_credentials 
 ( 
 $api_client 
 , 
  
 $client_id 
 , 
  
 $client_secret 
 , 
  
 $additional_scopes 
 ); 
 =pod 
 =head1 NAME 
 generate_user_credentials 
 =head1 DESCRIPTION 
 This example will create an OAuth2 refresh token for the Google Ads API for either a web 
 or desktop app OAuth client ID. 
 For web app client types, you must add B<http://127.0.0.1> to the "Authorize redirect URIs" 
 list in your L<Google Cloud Console project|https://console.developers.google.com/apis/credentials> 
 before running this example, where PORT defaults to 8080. Desktop app client types do not 
 require the local redirect to be explicitly configured in the Cloud console. 
 =head1 SYNOPSIS 
 generate_user_credentials.pl [options] 
 -help                       Show the help message. 
 -client_id                  The OAuth2 client id. 
 -client_secret              The OAuth2 client secret 
 -additional_scopes          [optional] Additional OAuth2 scopes seperated by comma. 
 =cut 
  
  
Create a Mobile Website
View Site in Mobile | Classic
Share by: