यहां एक सैंपल दिया गया है, जिसे अनुमति देने के लिए इस्तेमाल किया जा सकता है:
Java
// Copyright 2023 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. package shopping.css.samples.utils; 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.GoogleCredentials; import com.google.auth.oauth2.UserAuthorizer; import com.google.auth.oauth2.UserCredentials; import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; 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.regex.Matcher; import java.util.regex.Pattern; /** * Class that contains all the authentication logic, both for service accounts and to create an * OAuth 2 refresh token for the CSS API. * * <p>IMPORTANT FOR OAUTH: 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 Authenticator { // OAUTH2_CALLBACK_BASE_URI set to localhost by default private static final String OAUTH2_CALLBACK_BASE_URI = "http://127.0.0.1"; // Scopes for the generated OAuth2 credentials. The list here only contains the CSS 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/content").build(); public GoogleCredentials authenticate() throws IOException { Config config = Config.load(); if (config.getPath() == null) { throw new IllegalArgumentException( "Must update Config.java to set a configuration directory."); } File serviceAccountFile = new File(config.getPath(), "service-account.json"); System.out.printf("Checking for service account file at: %s%n", serviceAccountFile); if (serviceAccountFile.exists()) { System.out.println("Attempting to load service account credentials"); try (InputStream inputStream = new FileInputStream(serviceAccountFile)) { GoogleCredentials credential = GoogleCredentials.fromStream(inputStream); System.out.println("Successfully loaded service account credentials"); return credential; } } System.out.println("No service account file found."); // Non-service account OAuth flow below // First see if a refresh token exists, and if so, use it File tokenFile = new File(config.getPath(), "token.json"); System.out.printf("Checking for user credentials file at: %s%n", tokenFile); if (tokenFile.exists()) { System.out.println("Loading OAuth2 refresh token."); UserCredentials userCredentials = UserCredentials.fromStream(new FileInputStream(tokenFile)); System.out.println("Successfully loaded OAuth2 refresh token"); return userCredentials; } // If the refresh token does not exist, attempt to use client // credentials to get a refresh token File clientSecretsFile = new File(config.getPath(), "client-secrets.json"); if (!clientSecretsFile.exists()) { throw new IOException( "No authentication credentials found. Checked the paths " + serviceAccountFile.getCanonicalPath() + " and " + clientSecretsFile.getCanonicalPath() + ". Please read the accompanying README."); } System.out.println("Loading OAuth2 client credentials."); try (InputStream inputStream = new FileInputStream(clientSecretsFile)) { ClientId parsedClient = ClientId.fromStream(inputStream); String clientId = parsedClient.getClientId(); String clientSecret = parsedClient.getClientSecret(); // 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("", 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 new refresh token is: %s%n", userCredentials.getRefreshToken()); // Save the refresh token to be used for the future userCredentials.save(new File(config.getPath(), "token.json").getPath()); return userCredentials; } catch (IOException e) { throw new IOException( "Could not retrieve OAuth2 client credentials from the file " + clientSecretsFile.getCanonicalPath()); } } /** 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(Authenticator.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(); } } }