Как можете да получите профила в Google+ на текущия потребител, когато използвате вградената автентификация на Google Cloud Endpoint (Java)?

Моята настройка

Бекенд: Google App Engine (Java) с Google Cloud Endpoints използвайки вграденото в Endpoint удостоверяване

Frontend: AngularJS уеб приложение

проблем

Трябва да получа потребителския профил в Google+ за моите потребители. Ключовата дума „аз“ обикновено може да се използва за получаване на потребителския профил в Google+ на текущия потребител, но тъй като цялото удостоверяване в Google Cloud Endpoints се извършва под капака, така или иначе не виждам да получа идентификационни данни, нито токен за текущия потребител. Всичко, което получавате, е обектът com.google.appengine.api.users.User.

Има ли някакъв начин да получите потребителски идентификационни данни или токена за достъп, когато използвате вградената автентификация на Google Cloud Endpoint?

Забележка: ID на потребителския профил в Google+ е различен от ID на акаунт в Google.

Възможно решение

Бих могъл просто да използвам клиента на Google+ JS с ключовата дума „аз“ и да накарам потребителя да изпрати своя Google+ ID и след това впоследствие да го запазя и да го свържа с ID на своя акаунт в Google, но това би било невероятно несигурно, тъй като потребителят може да хакне пътя си до изпращане на идентификатора на всеки акаунт в Google+.


person Marc M.    schedule 19.06.2015    source източник


Отговори (2)


Възможно е да получите токена за потребителски достъп, когато използвате вградената автентификация на Google Cloud Endpoint.

  1. Добавете параметъра HttpServletRequest request към вашата крайна точка в Google Cloud, както е показано по-долу. Това ще ви позволи да получите необработената заявка.

  2. След това ще трябва да извлечете заглавката, наречена Удостоверяване. Това ще получи токен за достъп на носител, който ще ви позволи да създадете идентификационни данни, за да се представяте за удостоверения потребител.

  3. След това ще използвате този токен за достъп на носител, за да изградите com.google.api.client.googleapis.auth.oauth2.GoogleCredential обект. Това ще ви е необходимо, за да изградите услугата Plus.

  4. Използвайте създателя Plus, за да изградите обект на услуга Plus с идентификационните данни, които току-що създадохте.

Примерен код

@ApiMethod(path = "myPath")
public void myEndpoint(HttpServletRequest request, ParmOne paramOne, ...) throws OAuthRequestException {

    if (user == null) {
        throw new OAuthRequestException("Authentication error!");
    }

    GoogleCredential credentialAsUser = new GoogleCredential().setAccessToken(request.getHeader("Authorization").substring(7)); // Start string at index position 7 to remove prefix "Bearer" from token.

    Plus plus = new Plus.Builder(new UrlFetchTransport(), new JacksonFactory(), credentialAsUser).setApplicationName("my-app").build();
    Person profile = plus.people().get("me").execute();

}

Документация

Документите на Java за клиента Google Plus могат да бъдат намерени тук.

Документите на Java за инструкции относно създаването на идентификационни данни на Google могат да бъдат намерени тук.

person Marc M.    schedule 20.06.2015
comment
О благодаря много! Точно това търсех :) - person Jokus; 25.01.2016
comment
@Jokus Опитвал ли си някога това с Android Endpoints клиент? Не работи за мен. - person Marc M.; 31.01.2016
comment
Накарах го да работи само за няколко часа, сега отново се срива :( Това, което разбрах, е, че извикването на api от api-мениджъра генерира access_token в заглавката на заявката. Това работи с кода по-горе. Ако извикам api от моето приложение за android, заглавката ще съдържа id_token, който няма да работи с кода по-горе ... Някакви идеи как да променя този тип удостоверение се генерират по този начин в android: GoogleAccountCredential.usingAudience(this,"server:client_id:" + Constants.WEB_CLIENT_ID);. - person Jokus; 02.02.2016
comment
@Jokus Не знам дали можеш. Уведомете ме, ако разберете нещо. Може просто да кажа по дяволите и да получа профила от страна на Android. - person Marc M.; 03.02.2016
comment
@Jokus Подозирам, че ще работи, ако можете да накарате Google Sign-In да работи с Google Cloud Endpoints, но за съжаление не можах да накарам и това да работи. - person Marc M.; 03.02.2016
comment
Най-накрая успях! Както вече казах, GoogleAccountCredential.usingAudience изпраща id_token (много дълъг) в заглавката на заявката. За да получите access_token, просто използвайте credentials = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(Scopes.PLUS_LOGIN)); в приложението си и го изпратете на вашия API (например: new yourApi.Builder(AndroidHttp.newCompatibleTransport(),new JacksonFactory(), credentials);) По този начин кодът по-горе трябва да работи с приложения за Android ;) - person Jokus; 10.02.2016
comment
@Jokus Пич, ти си шефът! Направете отделен отговор и аз ще го гласувам. Това определено си заслужава отделен отговор. - person Marc M.; 11.02.2016

Допълнителен отговор за клиенти с Android

проблем

В допълнение към отговора на Марк е важно GoogleCredentials-Object да се нуждае от access_token в заглавката на заявката.

Ако извикате крайната точка с вашия apiExplorer или крайна точка на JavaScript, това токенът вече се сервира в заглавката за оторизация. Но ако следвате документите за клиент за Android, заглавката на вашите заявки съдържа id_token, така че GoogleCredentials.setAccessToken не работи.

Решение

За да промените типа на разрешението на access_token, просто създайте своя GoogleAccountCredential-Object в Android с usingOAuth2 вместо usingAudience.

Пример

Заменете този код в приложението си за Android

credential = GoogleAccountCredential.usingAudience(this,
"server:client_id:1-web-app.apps.googleusercontent.com");

с тази

credential = GoogleAccountCredential.usingOAuth2(this, 
Collections.singleton(Scopes.PLUS_LOGIN));

и го изпратете до вашия API, както е обяснено в документацията

Helloworld.Builder helloWorld = new Helloworld.Builder(AppConstants.HTTP_TRANSPORT,
  AppConstants.JSON_FACTORY,credential);
person Jokus    schedule 11.02.2016