restaurar - variables de entorno java linux
Autenticación API de Google en Java sin utilizar variable de entorno (5)
He configurado una aplicación de prueba simple para interactuar con la API de lenguaje natural de Google. Creé una cuenta de servicio y descargué las credenciales de JSON. Estoy ejecutando en una máquina de desarrollo local, así que configuro la variable de entorno GOOGLE_APPLICATION_CREDENTIALS
para que apunte al archivo JSON. Para que quede claro, esto funciona : la aplicación realiza con éxito algunas llamadas a la API y muestra los resultados.
Me gustaría eliminar la dependencia de la variable de entorno. ¿Cómo puedo usar la ubicación conocida del archivo JSON (o cualquier otro método) en la aplicación para crear el LanguageServiceClient
con esas credenciales?
Esto parece un hilo anterior pero compartiendo nuestros hallazgos para lo que vale.
Este ejemplo es para Google ImageAnnotatorClient, pero estoy bastante seguro de que es muy similar para LanguageServiceClient.
Las bibliotecas de Google de la vieja escuela (era del archivo P12) usan GoogleCredential frente a las nuevas GoogleCredentials. Se ven muy similares. Cavando en la jerarquía de tipos, encontré un FixedCredentialsProvider que parece hacer el truco.
Esto nos funcionó, pusimos en marcha la API de Google Vision con un archivo P12 existente sin variable de entorno. Parece que Google quiere que nos alejemos de esto, por lo que no recomendamos este enfoque a largo plazo.
// old-school Google Authentication
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
// Spring code
String pemFile = "yourPemFile.p12";
Resource r = new ClassPathResource(pemFile);
String serviceAccountEmail = "[email protected]";
// com.google.api.client.googleapis.auth.oauth2.GoogleCredential.Builder
Builder credentialBuilder = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountPrivateKeyFromP12File(r.getFile());
// Cloud API endpoints, make sure that the API is enabled
Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-vision");
GoogleCredential credential = credentialBuilder
.setServiceAccountScopes(scopes).build();
// copy over key values, note the additional "s", set some expiry
// com.google.auth.oauth2.GoogleCredentials
GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
.setPrivateKey(gc.getServiceAccountPrivateKey())
.setPrivateKeyId(gc.getServiceAccountPrivateKeyId())
.setClientEmail(gc.getServiceAccountId())
.setScopes(scopes)
.setAccessToken(new AccessToken(gc.getAccessToken(), new LocalDate().plusYears(1).toDate()))
.build();
// Latest generation Google libs, GoogleCredentials extends Credentials
CredentialsProvider cp = FixedCredentialsProvider.create(sac);
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(cp).build();
ImageAnnotatorClient googleApi = ImageAnnotatorClient.create(settings);
Puedes registrarte es así:
DatastoreOptions options = DatastoreOptions.newBuilder()
.setProjectId(PROJECT_ID)
.setAuthCredentials(AuthCredentials.createForJson(
new FileInputStream(PATH_TO_JSON_KEY))).build();
¿Eso ayuda?
Siempre puede pasar el archivo json completo como cadena de la siguiente manera:
CredentialsProvider credentialsProvider;
String credentials = "[YOUR JSON FILE CONTENT]";
try {
credentialsProvider
= FixedCredentialsProvider.create(
ServiceAccountCredentials.fromStream(new ByteArrayInputStream(credentials.getBytes())));
} catch (IOException ex) {
Logger.getLogger(GoogleNLPService.class.getName()).log(Level.SEVERE, null, ex);
}
LanguageServiceSettings.Builder languageServiceSettingsBuilder
= LanguageServiceSettings.newBuilder();
LanguageServiceSettings languageServiceSettings = languageServiceSettingsBuilder.setCredentialsProvider(credentialsProvider).build();
List<NamedEntity> entities = new ArrayList<>();
try (LanguageServiceClient language = LanguageServiceClient.create(languageServiceSettings)) {
...
}
Alternativamente, puede colocar su archivo json en la carpeta de recursos y luego leerlo como:
credentialsProvider
= FixedCredentialsProvider.create(
ServiceAccountCredentials.fromStream(new FileInputStream("./src/main/resources/FILENAME.json")));
Sin embargo, esta ruta relativa no funcionó cuando subí mi aplicación en Heroku. Entonces, he decidido usar la solución String.
Siguiendo los consejos de la respuesta de tokyohans anterior, puedo confirmar que esto funciona para LanguageServiceClient:
// old-school Google Authentication
GoogleCredential credential = null;
credential = GoogleCredential.fromStream(new FileInputStream("google.json"));
Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-language");
if (credential.createScopedRequired()) {
credential = credential.createScoped(scopes);
}
// copy over key values, note the additional "s", set some expiry
// com.google.auth.oauth2.GoogleCredentials
GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
.setPrivateKey(credential.getServiceAccountPrivateKey())
.setPrivateKeyId(credential.getServiceAccountPrivateKeyId())
.setClientEmail(credential.getServiceAccountId())
.setScopes(scopes)
.setAccessToken(new AccessToken(credential.getAccessToken(), new LocalDate().plusYears(1).toDate()))
.build();
// Latest generation Google libs, GoogleCredentials extends Credentials
CredentialsProvider cp = FixedCredentialsProvider.create(sac);
LanguageServiceSettings settings = (LanguageServiceSettings) LanguageServiceSettings.newBuilder().setCredentialsProvider(cp).build();
return LanguageServiceClient.create(settings);
Utilizamos una cuenta de servicio + GoogleCredential.Builder
- (tenga en cuenta que este ejemplo utiliza un archivo de credenciales en formato p12); el siguiente ejemplo:
private GoogleCredential authorize() throws IOException, GeneralSecurityException
{
return new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(serviceAccount)
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser(serviceAccountUser)
// variable p12File is a String w/ path to the .p12 file name
.setServiceAccountPrivateKeyFromP12File(new java.io.File(p12File))
.build();
}