Saltar al contenido

¿Cómo obtener el token de acceso después de que el usuario haya iniciado sesión desde Gmail en Android?

Bienvenido a nuestra web, aquí vas a hallar la solucíon que buscabas.

Solución:

Para sus requisitos, puede utilizar el siguiente código:

En primer lugar, asegúrese de tener una Web ID de cliente de OAuth 2.0:


    ...e4p8.apps.googleusercontent.com

Luego, dentro de la clase de actividad:

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ...

    // For sample only: make sure there is a valid server client ID.
    validateServerClientID();

    // [START configure_signin]
    // Configure sign-in to request offline access to the user's ID, basic
    // profile, and Google Drive. The first time you request a code you will
    // be able to exchange it for an access token and refresh token, which
    // you should store. In subsequent calls, the code will only result in
    // an access token. By asking for profile access (through
    // DEFAULT_SIGN_IN) you will also get an ID Token as a result of the
    // code exchange.
    String serverClientId = getString(R.string.server_client_id);
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
            .requestServerAuthCode(serverClientId)
            .requestEmail()
            .build();
    // [END configure_signin]

    // Build GoogleAPIClient with the Google Sign-In API and the above options.
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();


private void getAuthCode() 
    // Start the retrieval process for a server auth code.  If requested, ask for a refresh
    // token.  Otherwise, only get an access token if a refresh token has been previously
    // retrieved.  Getting a new access token for an existing grant does not require
    // user consent.
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_GET_AUTH_CODE);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RC_GET_AUTH_CODE) 
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        Log.d(TAG, "onActivityResult:GET_AUTH_CODE:success:" + result.getStatus().isSuccess());

        if (result.isSuccess()) 
            // [START get_auth_code]
            GoogleSignInAccount acct = result.getSignInAccount();
            String authCode = acct.getServerAuthCode();

            // Show signed-in UI.
            mAuthCodeTextView.setText(getString(R.string.auth_code_fmt, authCode));
            updateUI(true);

            // TODO(user): send code to server and exchange for access/refresh/ID tokens.
            // [END get_auth_code]
         else 
            // Show signed-out UI.
            updateUI(false);
        
    

Puede ver el código completo en el siguiente ServerAuthCodeActivity.java

El resultado, si usa esa muestra, se parece a la siguiente captura de pantalla:

Captura de pantalla de BNK

Luego, puede seguir los pasos mencionados en la documentación de Google a continuación (desde el paso # 3. Envíe el código de autenticación al backend de su aplicación mediante HTTPS POST):

Inicio de sesión de Google para Android: habilitación del acceso del lado del servidor


ACTUALIZACIÓN: a partir de los comentarios, si desea obtener el token de acceso directamente desde la aplicación cliente de Android, use el siguiente código de muestra (reemplazado con su client_id, client_secret y el código de autenticación)

OkHttpClient client = new OkHttpClient();
    RequestBody requestBody = new FormEncodingBuilder()
            .add("grant_type", "authorization_code")
            .add("client_id", "812741506391-h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com")
            .add("client_secret", "clientSecret")
            .add("redirect_uri","")
            .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8")
            .build();
    final Request request = new Request.Builder()
            .url("https://www.googleapis.com/oauth2/v4/token")
            .post(requestBody)
            .build();
    client.newCall(request).enqueue(new Callback() 
        @Override
        public void onFailure(final Request request, final IOException e) 
            Log.e(LOG_TAG, e.toString());                
        

        @Override
        public void onResponse(Response response) throws IOException 
            try 
                JSONObject jsonObject = new JSONObject(response.body().string());
                final String message = jsonObject.toString(5);
                Log.i(LOG_TAG, message);                    
             catch (JSONException e) 
                e.printStackTrace();
            
        
    );

Por favor use compile 'com.squareup.okhttp:okhttp:2.6.0' (la versión 3-RC1 tendrá diferentes clases)

Con una respuesta exitosa, tendrá la siguiente información en logcat:

I/onResponse: 
              "expires_in": 3600,
              "token_type": "Bearer",
              "refresh_token": "1/xz1eb0XU3....nxoALEVQ",
              "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA",
              "access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4"
         

BNK lo tiene acertado en su mayor parte. La clase de actividad es la misma que la respuesta de BNK solo con agregar la parte OkHttp una vez que obtenga la GoogleSignInAccount en el onActivityResult() método.

Pero todavía recibía errores con la parte de solicitud OkHttp. Finalmente, después de algunas pruebas (y algo de suerte) en Postman, descubrí que me faltaba el parámetro id_token. A la solicitud OkHttp le faltaba un parámetro, es decir, id_token. Use el token de identificación que obtiene de GoogleSignInAccount algo como esto

GoogleSignInAccount acct = result.getSignInAccount();
String idTokenString = acct.getIdToken();

Ahora use este idTokenString junto con todos los parámetros en la parte OkHttp de la respuesta de BNK algo así

...

RequestBody requestBody = new FormEncodingBuilder()
            .add("grant_type", "authorization_code")
            .add("client_id", "alpha-numeric-string-here.apps.googleusercontent.com")
            .add("client_secret", "clientSecret")
            .add("redirect_uri","")
            .add("code", "4/4-alphabetic-string-here")
            .add("id_token", idTokenString) // Added this extra parameter here
            .build();

...

La respuesta que se obtiene es la misma que la respuesta de BNK


  "access_token": "ya29.CjBgA_I58IabCJ...remainingAccessTokenHere",
  "token_type": "Bearer",
  "expires_in": 3577,
  "id_token": "eyJhbGciOiJS...veryLongStringHere"

Ahora envíe este access_token a su servidor backend para autenticarse tal como solía hacer durante los tiempos de GoogleAuthUtil y PlusAPI.

Espero que esto ayude 🙂 ¡Un agradecimiento especial a BNK!

Aquí está mi enfoque con Kotlin, (esta es mi primera respuesta en StackOverflow, si hay algo mal, falta o si puedo hacerlo mejor, avíseme)

En la actividad de inicio de sesión

private fun configureGoogleSignIn() 
    mGoogleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(getString(R.string.default_web_client_id))
        .requestServerAuthCode(getString(R.string.server_client_id_oauth))
        .requestEmail()
        .build()
    mGoogleSignInClient = GoogleSignIn.getClient(this, mGoogleSignInOptions)


private fun signInWithGoogle() 
    val signInIntent: Intent = mGoogleSignInClient.signInIntent
    startActivityForResult(signInIntent, RC_SIGN_IN)

Asegúrese de llamar a la función configureGoogleSignIn () en OnCreate

Entonces para obtener el resultado

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) 
    super.onActivityResult(requestCode, resultCode, data)

    callbackManager?.onActivityResult(requestCode, resultCode, data)


    if (requestCode == RC_SIGN_IN) 
        val tag = "onActivityResult RC_SIGN_IN"
        val task: Task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try 
            val account = task.getResult(ApiException::class.java)
            firebaseAuthWithGoogle(account!!)
            getIdTokenFromFirebaseAuth()

            var acct = GoogleSignIn.getLastSignedInAccount(this)
            if (acct != null) 
                var personName = acct.displayName
                firstName = acct.givenName!!
                lastName = acct.familyName!!
                userEmail = acct.email!!
                authCode = acct.serverAuthCode!! //THIS is what you looking for
                googleIdToken2 = acct.idToken!!
                Log.d(tag, authCode)
                Log.d(tag, googleIdToken2)
                var personId = acct.id
                //todo pegar foto do google e por no cadastro do usuario
                var personPhoto = acct.photoUrl
                spinner.visibility = View.GONE
                getGoogleAccessToken()
            
         catch (e: ApiException) 
            spinner.visibility = View.GONE
            infoToUserTextView.text = getString(R.string.ops_we_had_a_problem)
        
    

Luego haga una llamada a la API de Google (estoy usando Retrofit), usando esta interfaz haga:

@FormUrlEncoded
@POST
fun getAccessTokenGoogle(
    @Url url: String,
    @Field("grant_type") grant_type: String,
    @Field("client_id") client_id: String,
    @Field("client_secret") client_secret: String,
    @Field("redirect_uri") redirect_uri: String,
    @Field("code") authCode: String,
    @Field("id_token") id_token: String
):Call

Aquí está el GoogleSignInAccessTokenDataClass

data class GoogleSignInAccessTokenDataClass(
val access_token: String,
val expires_in: Int,
val id_token: String,
val token_type: String

)

Haga la llamada en la actividad de inicio de sesión

private fun getGoogleAccessToken()
    val call = RetrofitGet().userInfoGson().getAccessTokenGoogle(
        grant_type = "authorization_code", client_id = getString(R.string.server_client_id_oauth),
        client_secret = getString(R.string.server_client_secret_oauth), redirect_uri = "",
        authCode = authCode, id_token =googleIdToken2, url = googleTokenUrl
    )

    call.enqueue(object : Callback
        val tag = "getGoogleAccessToken"
        override fun onFailure(call: Call, t: Throwable) 
            Log.e(tag, t.toString())
        

        override fun onResponse(
            call: Call,
            response: Response
        ) 
            if (response.isSuccessful)
                val responseBody = response.body()
                googleAccessToken = responseBody!!.access_token
                Log.d(tag, googleAccessToken)
            else
                try 
                    val responseError = response.errorBody()!!.string()
                    Log.e(tag, responseError)
                catch (e:Exception)Log.e(tag, e.toString())
            
        
    )

Puntuaciones y reseñas

Recuerda algo, que te brindamos la opción de glosar tu experiencia si topaste tu atascamiento a tiempo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *