Google Java API для AuthorizationCodeInstalledApp для веб-приложения - PullRequest
0 голосов
/ 30 апреля 2018

У меня некоторая путаница с документацией API и моим сценарием использования, а также с тем, как обращаться с токеном авторизации для моего веб-приложения. У меня есть веб-служба, в которой пользователи входят в мое приложение (не приложение Google), и мне нужно, чтобы они предоставили мою авторизацию службы (Java с Spring Boot) для загрузки на Youtube. Позже мне нужно будет использовать эту авторизацию «в автономном режиме» для загрузки видео на их канал, без того, чтобы они входили в мой сервис (функция типа «автоматическая публикация»). Я пробовал множество методологий, и, как правило, это работает, но столкнулся с некоторыми трудностями для чистой реализации:

        GoogleAuthorizationCodeFlow flow =
                new GoogleAuthorizationCodeFlow.Builder(
                        httpTransport, JSON_FACTORY, clientSecrets, scopes)
                        .setDataStoreFactory(dataStoreFactory)
                        .setAccessType("offline")
                        .build();

        credential = new AuthorizationCodeInstalledApp(
                flow, new LocalServerReceiver()).authorize("user");

Создает консольное сообщение с URL-адресом, чтобы пользователь мог открыть его в своем браузере. Я бы надеялся, что пользователь будет фактически перенаправлен. Я не хочу, чтобы это был ручной процесс, когда я должен быть за консолью, а затем предоставить пользователю URL-адрес, возвращенный из этого процесса, чтобы он мог открыть его в своем браузере. Насколько я понимаю, LocalServerReceiver предназначен для обработки фактического ответа токена доступа после авторизации пользователем. Я подробно рассмотрел это и не смог найти ни одного решения для документа или чего-либо в примерах, где это не приводило к консольному сообщению с эффектом «вставьте следующий URL в ваш браузер ....» с URL авторизации .

Я пытался использовать GoogleAuthorizationCodeFlow с:

        GoogleAuthorizationCodeFlow flow = (new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, scopes))
                .setDataStoreFactory(dataStoreFactory)
                .setAccessType("offline")
                .build();

        return flow.newAuthorizationUrl()
                .setScopes(scopes)
                .setAccessType("offline")
                .setClientId(clientSecrets.getDetails().getClientId())
                .setRedirectUri(redirectionUrl)
                .toString();

Я поставил "/ oauth2-callback" для моего redirectionUrl, и это работает (в некоторой степени). Я получаю пользователя на страницу авторизации Google, он авторизует его, и я получаю токен для моей конечной точки «обратного вызова» («/ oauth2-callback»), но этот токен, похоже, не полностью авторизован. Я храню его в своем хранилище данных, и вижу его там, но когда я пытаюсь использовать его в автономном режиме, я получаю ошибку авторизации. Просматривая больше документов, я наткнулся на этот оставшийся код для обработки токена, отправленного обратно на мой обратный вызов:

        GoogleTokenResponse response = flow.newTokenRequest(token)
                .setRedirectUri(redirectUrl).execute();

        Credential credential = flow.createAndStoreCredential(response, "user");

Проблема в том, что я уже в моей конечной точке обратного вызова, и для этого нужен еще один redirectURL. Токен из авторизации не работает в автономном режиме, пока я не выполню этот «newTokenRequest», для которого требуется еще один URL перенаправления. Кажется, требуется исходный redirectURL, который был в вызове flow.newAuthorizationUrl (), но когда выполняется newTokenRequest, он производит еще один обратный вызов в этот URL, и я в итоге получаю ошибку «токен уже погашен».

В любом из моих вышеописанных сценариев с AuthorizationCodeInstalledApp или с помощью flow.newAuthorizationUrl () с URL-адресом обратного вызова, который я обрабатываю с помощью токена с flow.newTokenRequest и flow.createAndStoreCredential, я получаю учетные данные, которые позже смогу использовать автономно. Но у меня проблемы с получением плавного пользовательского опыта в любом из них.

Чего мне не хватает в моем сценарии?

1 Ответ

0 голосов
/ 30 апреля 2018

Согласно документации после вызова метода authorize, он вызывает метод onAuthorization, который в конечном итоге вызывает метод browse с использованием authorizationUrl, чтобы попытаться автоматически открыть браузер.

public static void browse(String url) {
Preconditions.checkNotNull(url);
// Ask user to open in their browser using copy-paste
System.out.println("Please open the following address in your browser:");
System.out.println("  " + url);
// Attempt to open it in the browser
try {
  if (Desktop.isDesktopSupported()) {
    Desktop desktop = Desktop.getDesktop();
    if (desktop.isSupported(Action.BROWSE)) {
      System.out.println("Attempting to open that address in the default browser now...");
      desktop.browse(URI.create(url));
    }
  }
} catch (IOException e) {
  LOGGER.log(Level.WARNING, "Unable to open browser", e);
} catch (InternalError e) {
  // A bug in a JRE can cause Desktop.isDesktopSupported() to throw an
  // InternalError rather than returning false. The error reads,
  // "Can't connect to X11 window server using ':0.0' as the value of the
  // DISPLAY variable." The exact error message may vary slightly.
  LOGGER.log(Level.WARNING, "Unable to open browser", e);
}

}

Он должен быть внутри блока try, где он пытается открыть браузер. Ищите Desktop.isDesktopSuported and desktop.isSupported(Action.BROWSE) верно для платформы, на которой вы запускаете вашу программу.

Редактировать: Приведенный выше пример взят из службы Gmail, но oauth-процесс авторизации одинаков для всех продуктов Google AFAIK.

...