Создать AccessToken для GCP Speech to Text на сервере для использования в Android / iOS - PullRequest
0 голосов
/ 17 января 2020

Работа над проектом, который объединяет текстовые API Google Cloud в среде android и iOS. Пробежался по предоставленному коду примера (https://cloud.google.com/speech-to-text/docs/samples) и смог запустить его. Использовал их в качестве шаблона для добавления голоса в мое приложение, однако в примерах есть серьезная опасность, особенно при создании AccessToken (фрагмент Android ниже):

// ***** WARNING *****
// In this sample, we load the credential from a JSON file stored in a raw resource
// folder of this client app. You should never do this in your app. Instead, store
// the file in your server and obtain an access token from there.
// *******************
final InputStream stream = getResources().openRawResource(R.raw.credential);
try {
   final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
      .createScoped(SCOPE);
   final AccessToken token = credentials.refreshAccessToken();

Это было прекрасно для разработки и тестируйте локально, но, как указывает комментарий, сохранить файл учетных данных в сборку производственного приложения небезопасно. Поэтому мне нужно заменить этот код на запрос от конечной точки сервера. Кроме того, мне нужно написать конечную точку, которая примет запрос и передаст обратно токен. Хотя я нашел несколько очень интересных руководств, связанных с библиотеками Firebase Admin, генерирующими токены, я не смог найти ничего, связанного с выполнением аналогичной операции для GCP apis.

Любые предложения / документация / примеры, которые могли бы указать мне на право направление приветствуется!

Примечание. Конечной точкой сервера будет среда Node.js.

Ответы [ 2 ]

1 голос
/ 31 января 2020

Извините за задержку, я смог заставить все это работать вместе, и теперь я только возвращаюсь, чтобы опубликовать чрезвычайно упрощенное руководство. Для начала я установил следующую библиотеку в проекте конечной точки сервера https://www.npmjs.com/package/google-auth-library

В конечной точке сервера в этом случае не хватает какой-либо аутентификации / авторизации и т. Д. c для простоты. Я оставлю эту часть на ваше усмотрение. Мы также собираемся сделать вид, что эта конечная точка достижима с https://www.example.com/token

Ожидается, что вызов https://www.example.com/token приведет к ответу со строковым токеном, номер для expires и некоторая дополнительная информация о том, как был создан токен:

ie:

{"token":"sometoken", "expires":1234567, "info": {... additional stuff}}

Также для этого примера я использовал файл ServiceAccountKey, который будет храниться в сервер. Рекомендуемый маршрут - настроить переменную среды сервера и использовать https://cloud.google.com/docs/authentication/production#finding_credentials_automatically, однако это для примера и достаточно просто для быстрого тестирования. Эти файлы выглядят примерно так: (система чести не крадет мой закрытый ключ)

ServiceAccountKey. json

{
  "type": "service_account",
  "project_id": "project-id",
  "private_key_id": "378329234klnfgdjknfdgh9fgd98fgduiph",
  "private_key": "-----BEGIN PRIVATE KEY-----\nThisIsTotallyARealPrivateKeyPleaseDontStealIt=\n-----END PRIVATE KEY-----\n",
  "client_email": "project-id@appspot.gserviceaccount.com",
  "client_id": "12345678901234567890",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/project-id%40appspot.gserviceaccount.com"
}

Так что здесь это простая конечная точка, которая выдает AccessToken и число, указывающее, когда истекает токен (так что вы можете вызвать новый) позже.

конечная точка. js

const express = require("express");
const auth = require("google-auth-library");
const serviceAccount = require("./ServiceAccountKey.json");

const googleauthoptions = {
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
    credentials: serviceAccount
};

const app = express();
const port = 3000;
const auth = new auth.GoogleAuth(googleauthoptions);
auth.getClient().then(client => {
    app.get('/token', (req, res) => {
        client
            .getAccessToken()
            .then((clientresponse) => {
            if (clientresponse.token) {
                return clientresponse.token;
            }
            return Promise.reject('unable to generate an access token.');
        })
            .then((token) => {
            return client.getTokenInfo(token).then(info => {
                const expires = info.expiry_date;
                return res.status(200).send({ token, expires, info });
            });
        })
            .catch((reason) => {
            console.log('error:  ' + reason);
            res.status(500).send({ error: reason });
        });
    });
    app.listen(port, () => {
        console.log(`Server is listening on https://www.example.com:${port}`);
    });
    return;
});

Почти готово сейчас, будет использовать android Например. Первый клип будет таким, каким он был изначально извлечен из файла устройства:

public static final List<String> SCOPE = Collections.singletonList("https://www.googleapis.com/auth/cloud-platform");
    final GoogleCredentials credentials = GoogleCredentials.fromStream(this.mContext.getResources().openRawResource(R.raw.credential)).createScoped(SCOPE);
      final AccessToken token = credentials.refreshAccessToken();
final string token = accesstoken.getTokenValue();
final long expires = accesstoken.getExpirationTime().getTime()
final SharedPreferences prefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE);
    prefs.edit().putString(PREF_ACCESS_TOKEN_VALUE, value).putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, expires).apply();
    fetchAccessToken();

Теперь мы получили наш токен из конечной точки через inte rnet (не показан), с токеном и информацией об истечении срока действия. обрабатывать его так же, как если бы оно было сгенерировано на устройстве:

//
// lets pretend endpoint contains the results from our internet request against www.example.com/token
final string token = endpoint.token;
final long expires = endpoint.expires
    final SharedPreferences prefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE);
    prefs.edit().putString(PREF_ACCESS_TOKEN_VALUE, value).putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, expires).apply();
    fetchAccessToken();

В любом случае, надеюсь, это будет полезно, если у кого-то возникнет аналогичная потребность.

0 голосов
/ 31 января 2020
...