API Google Java для авторизации

У меня есть некоторая путаница с документацией API и моим вариантом использования, а также с тем, как обрабатывать токен авторизации для моего веб-приложения. У меня есть веб-служба, в которой пользователи входят в мое приложение (а не в приложение Google), и мне нужно, чтобы они предоставили авторизацию моей службы (Java с загрузкой Spring) для загрузки на 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");

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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 282
1

Ответы 1

Согласно документации, после вызова метода 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.isDesktopSuportedand desktop.isSupported(Action.BROWSE) подходит для платформы, на которой вы запускаете свою программу.

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

С моей службой, работающей под tomcat на сервере. Класс служебной программы Oracle Desktop является частью пакета awt, который «позволяет приложению Java запускать связанные приложения, зарегистрированные на собственном рабочем столе, для обработки URI или файла». Поскольку это работает на сервере, с пользователем, подключенным через сеанс браузера через сервлет, который создает AuthorizationCodeInstalledApp.authorize (), я не думаю, что доступен «родной» рабочий стол, и именно поэтому я получаю консольный вывод. Может быть, я не могу использовать для этого AuthorizationCodeInstalledApp ??

user2989397 01.05.2018 00:55

Приведенный выше код предназначен для работы на стороне клиента. Когда вы запускаете его, он пытается открыть браузер, но, поскольку вы запускаете его на сервере, браузер не отображается. Как передать результат клиентам, если вы вызываете это на стороне сервера? И если пользователь подключается к вашей системе через браузер, вы можете изменить свой дизайн, чтобы запустить этот процесс авторизации на стороне клиента.

Emre Dalkiran 01.05.2018 07:44

Это был мой «путь 2». В моем описании первоначального сообщения начну с «Я пробовал использовать GoogleAuthorizationCodeFlow с: ...». Я пошел на получение URL-адреса авторизации и перенаправления пользователя на него, что работает. Но последующая обработка кода авторизации вызывает второе обращение по URL-адресу обратного вызова, что меня огорчает. Вот где я сейчас сосредоточен.

user2989397 01.05.2018 15:28

Другие вопросы по теме