2015-03-10 1 views
1

Я хочу получить код авторизации, чтобы включить API-интерфейс на стороне сервера для моего приложения. Я делаю этот процесс в Unity3D с плагином сервисов Google Play для Unity. У меня есть функция, которая вызывает нативный функция getToken() из класса GoogleAuthUtils:Google+ getToken() throws UserRecoverableAuthException: NeedPermission

public string GetToken() { 
      string token = null; 
      Debug.Log("Before RetrieveUserEmail"); 
      string email = RetrieveUserEmail() ?? "NULL"; 
      Debug.Log("After RetrieveUserEmail email: " + email); 
      string scope = "oauth2:server:client_id:" + "666666666666-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com" 
       + ":api_scope:" + "https://www.googleapis.com/auth/plus.login"; 
      using (AndroidJavaClass jc_unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"), 
       jc_gau = new AndroidJavaClass("com.google.android.gms.auth.GoogleAuthUtil")) { 
       using(AndroidJavaObject jo_Activity = jc_unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) { 
        token = jc_gau.CallStatic<string>("getToken", jo_Activity, email, scope); 
       } 
      } 
      Debug.Log("Token " + token); 
      return token; 
     } 

, но я получаю AndroidJavaException: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission

Эта функция швы исправным, поскольку он работает с

string scope = "audience:server:client_id:" + "666666666666-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com" 

и возвращает токен аудитории.

Я не представляю, что я делаю неправильно.

Любые предложения?

Или, может быть, Вы можете уточнить, что с помощью URL-вызов:

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/plus.login&client_id=666666666666-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com&response_type=code&redirect_uri=http://someurl.com/oauth2callback

перенаправляет меня на URL-адрес, как

http://someurl.com/oauth2callback?code=4/YUVerNRxRQ8_XHPJ4USfjhYLCZ-fKoQyD1v5H_cZH_o.IvzKlyDEVOcVrjMoGjtSfTpyjkcImAI&authuser=0&num_sessions=1&session_state=14ac991a51396ecb690abac27e676846c7a8297e..c560&prompt=none

, который имеет в коде параметра = 4/YUVer ..

- это тот же самый код, который я пытаюсь получить через функцию Unity?

Благодарим заранее, я буду признателен за любую помощь.

ответ

0

Несколько вещей, которые могли бы стоить проверять:

  • Что вы перенаправлением URI?

Когда вы делаете запрос от Android, ваш URI перенаправления будет URI-адреса перенаправления для конкретного устройства, urn: ietf: wg: oauth: 2.0: oob.

  • Вы (или ваш пользователь) отменили действие с авторизации?

Ошибка, которую вы получаете, указывает на то, что пользователь нажал кнопку отмены при авторизации приложения (или не нажал кнопку подтверждения). Если вы получаете код авторизации (строка 4/YUY ....), это не должно происходить.

  • Является ли этот токен обменным правом?

Существует 3 важных типа ответов OAuth для authZ, токена доступа, токена обновления и кода авторизации. Если вы пытаетесь обменять токен доступа (или обновить токен) в качестве кода auth, ответы не будут иметь никакого смысла. Убедитесь, что вы используете код авторизации из getToken и передаете правильно подобранный URI перенаправления при выполнении обмена токенами.

Возвращаясь к вашим комментариям, это имеет смысл:

является то, что код ЖЕ один, как я пытаюсь получить с помощью функции Unity?

Код, который вы получаете после перенаправления сервера OAuth, является кодом, который вы хотите, и он возвращается с Android в getToken. Для получения дополнительной информации о получении/обмене кодом, ознакомьтесь с этой статьей блога на Google+ Android Client & Server Sign-In.

Демонстрацию о том, как получить код, см. На странице Haiku+ Android client. Соответствующий код:

public String getCodeSynchronous() throws GoogleAuthException, CodeException { 
    StringBuilder scopeString = new StringBuilder(""); 
    for (String scope : Constants.SCOPES) { 
     scopeString.append(" ").append(scope); 
    } 
    String scope = new StringBuilder("oauth2:server:client_id:") 
      .append(Constants.SERVER_CLIENT_ID) 
      .append(":api_scope:") 
      .append(scopeString.toString()) 
      .toString(); 
    Bundle appActivities = new Bundle(); 
    String types = TextUtils.join(" ", Constants.ACTIONS); 
    appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES, types); 

    String code = null; 
    try { 
     code = GoogleAuthUtil.getToken(
       mContext, 
       mAccountName, 
       scope, 
       appActivities); 
     // Immediately invalidate so we get a different one if we have to try again. 
     GoogleAuthUtil.invalidateToken(mContext, code); 
    } catch (IOException e) { 
     Log.e(TAG, e.getMessage(), e); 
     throw new CodeException("Error: could not establish connection to server."); 
    } 

    return code; 
} 

О том, как обменять код на стороне сервера, см Haiku+ Java server:

try { 
    // Upgrade the authorization code into an access and refresh token. 
    return new GoogleAuthorizationCodeTokenRequest(HaikuPlus.TRANSPORT, 
    HaikuPlus.JSON_FACTORY, 
    getClientId(), 
    getClientSecret(), 
    authorization, 
    redirectUri).execute(); 

} catch (TokenResponseException e) { 
    //Failed to exchange authorization code. 
    logger.log(Level.INFO, "Failed to exchange auth code; return 400", e); 
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 
    return null; 
} catch (IOException e) { 
    logger.log(Level.INFO, "Failed to exchange auth code; return 400", e); 
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 
    return null; 
} 
+0

Благодарим за ответ. Первое, что есть URI: На консоли разработчика для Android-приложения он имеет следующие значения: urn: ietf: wg: oauth: 2.0: oob http: // localhost. Должен ли я использовать идентификатор клиента из приложения Android или веб-приложения? Второе: без отмены, после входа в систему через плагин Unity. Я вызываю свой метод GetToken(). И этот код (4/YUV), который я пытаюсь получить из этого метода. В моем вопросе после «Или, может быть, вы можете уточнить ...» я хотел спросить, что URL-адрес возвращает тот же код, который я пытаюсь получить через скрипт. Мне не нужны токены, такие как токен доступа, токен обновления, только код авторизации. Спасибо за ссылку, я посмотрю. –

+0

Добавление дополнительных примеров. – class

+0

Хорошо, это, вероятно, решение для меня, для обработки UserRecoverableAuthException. Я написал свой собственный плагин, чтобы получить токен, но при предоставлении автономного доступа происходит сбой приложений. Если бы вы могли, взгляните на мою проблему, пожалуйста: [issue] (http://stackoverflow.com/questions/29489461/google-gettoken-crash) –

0

Я имел такой же вопрос. Так я и решил.

Шаг 1: Я следовал за документом Google по адресу Try Sign-In for Android. Итак, у меня был вход в систему. Я должен был следовать этому учебнику Start Integrating Google Sign-In into Your Android App создать «идентификатор клиента для Android»

Шаг 2: Точно так же, в то же самое время, когда я создал «идентификатор клиента для Android», я должен был создать «идентификатор клиента для Web ». Этот шаг дал мне «Идентификатор клиента для Интернета», который я буду использовать позже.

Шаг 3:

Получить токен после этой обучающей программы "AUTHENTICATE с внутренним сервером". В методе onConnected когда знак, добавьте

GetIdTokenTask getIdTokenTask = new GetIdTokenTask(); 
getIdTokenTask.execute(); 

Вы можете найти класс GetIdTokenTask после урока « Authenticate с внутренним сервером». Ниже приведен пример метода onConnected.

@Override 
public void onConnected(Bundle bundle) { 
    // onConnected indicates that an account was selected on the device, that the selected 
    // account has granted any requested permissions to our app and that we were able to 
    // establish a service connection to Google Play services. 
    Log.d(TAG, "onConnected:" + bundle); 
    mShouldResolve = false; 

    if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) { 
     Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient); 

     Log.d(TAG, "onConnected:" + "start GetIdTokenTask"); 

     GetIdTokenTask getIdTokenTask = new GetIdTokenTask(); 
     getIdTokenTask.execute(); 
    } else { 
     Log.d(TAG, "onConnected:" + "Cannot get current person's information."); 
    } 
    // Show the signed-in UI 
    showSignedInUI(); 
} 

Шаг 4: Настройка SERVER_CLIENT_ID, которые мы можем получить из шага 2 в GetIdTokenTask класса

Вот пример GetIdTokenTask.

private class GetIdTokenTask extends AsyncTask<Void, Void, String> { 

    @Override 
    protected String doInBackground(Void... params) { 
     String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient); 
     Account account = new Account(accountName, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE); 
     String scopes = "audience:server:client_id:" + SERVER_CLIENT_ID; // Not the app's client ID. 
     try { 
      return GoogleAuthUtil.getToken(getApplicationContext(), account, scopes); 
     } catch (IOException e) { 
      Log.e(TAG, "Error retrieving ID token.", e); 
      return null; 
     } catch (GoogleAuthException e) { 
      Log.e(TAG, "Error retrieving ID token.", e); 
      return null; 
     } 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     Log.i(TAG, "ID token: " + result); 
     if (result != null) { 
      // Successfully retrieved ID Token 
      // ... 
     } else { 
      // There was some error getting the ID Token 
      // ... 
     } 
    } 

} 
Смежные вопросы