Inicio de sesión con Google sin Google Play Services

Daniel Mendoza
Huawei Developers Latinoamérica
4 min readAug 11, 2020

Como seguramente has escuchado, los nuevos teléfonos Huawei ya no pueden incluir los Google Play Services. Esto significa que si tu aplicación implementa el inicio de sesión con Google, este botón dejará de funcionar y podría causar que tu aplicación se detenga en algunos dispositivos.

Afortunadamente Google cuenta con APIs web que se pueden consumir sin necesidad de los Play Services. en este artículo implementaremos el inicio de sesión con Google, con ayuda del la librería App Auth.

Requerimientos

  • Android Studio
  • Una App de Android que requiera inicio de sesión

Configuración del proyecto

Para poder acceder a las APIs de Google, nuestro proyecto necesita obtener credenciales para identificarse con el servidor OAUTH. Crea o selecciona un proyecto en la Consola de Google APIs.

Ve a Credentials > Create credentials >OAUTH client ID

Selecciona Android de la lista desplegable e ingresa la informaci[on de tu App.

Haz clic en Create y se mostrará tu Client ID. Necesitarás este dato más adelante.

Añadiendo la librería AppAuth

AppAuth es una librería de código abierto que nos permite comunicar nuestras aplicaciones Android con servicios OAUTH 2.0. Para integrar AppAuth en nuestro proyecto, basta con agregar las siguietes dependencias a nuestro archivo Build.gradle.

implementation 'net.openid:appauth:0.7.1'
implementation 'com.squareup.okio:okio:1.14.1'

Añade esto dentro de defaultConfig en tu Build.gradle

manifestPlaceholders = [
'appAuthRedirectScheme': 'com.googleusercontent.apps.PREFIX'
]

AppAuth abrirá la página de inicio de sesión en una pestaña del navegador que esté configurado por defecto. Añade lo siguiente a tu AndroidManifest.xml para capturar el resultado del inicio de sesión.

<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"><intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/><category android:name="android.intent.category.BROWSABLE"/><data android:scheme="com.hms.demo.appauthdemo"/></intent-filter></activity>

Haciendo la solicitud

Añade el botón de inicio de sesión con Google al Activity o Fragment dónde realizas el Login.

<com.google.android.gms.common.SignInButton
android:id="@+id/google_sign_in_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/button_margin"
/>

Añade el siguiente código al evento OnCLick de tu botón para solicitar la autorización del usuario para acceder a su información personal. Reemplaza el CLIENT_ID con el ID generado previamente y PACKAGE_NAME con el packagename de tu app.

val serviceConfig=AuthorizationServiceConfiguration(
Uri.parse("https://accounts.google.com/o/oauth2/auth"), // authorization endpoint
Uri.parse("https://oauth2.googleapis.com/token")); // token endpoint
val authRequestBuilder = AuthorizationRequest.Builder(
serviceConfig, // the authorization service configuration
CLIENT_ID, // the client ID, typically pre-registered and static
ResponseTypeValues.CODE, //
Uri.parse("$PACKAGE_NAME:/oauth2redirect")
) // the redirect URI to which the auth response is sent
authRequestBuilder.setScope("openid email profile")
val authRequest=authRequestBuilder.build()
val authService = AuthorizationService(this)
val authIntent = authService.getAuthorizationRequestIntent(authRequest)
startActivityForResult(authIntent, RC_AUTH)

Sobreescribe el método onActivityResult para capturar la respuesta de la solicitud.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_AUTH) {
if (data != null) {
val response = AuthorizationResponse.fromIntent(data)
val ex = AuthorizationException.fromIntent(data)
val authState = AuthState(response, ex)
if (response != null) {
val service = AuthorizationService(this)
service.performTokenRequest(
response.createTokenExchangeRequest()
) { tokenResponse, exception ->
if (exception != null) {
Log.e(TAG, "Token Exchange failed", exception)
} else {
if (tokenResponse != null) {
authState.update(tokenResponse, exception)
Log.e(
TAG,
"Token Response [ Access Token: ${tokenResponse.accessToken}, ID Token: ${tokenResponse.idToken}"
)
}
}
}
}
}
}
}

Obteniendo la información del usuario

Si la solicitud fue exitosa, obtendrás un access token en el método onActivityResult. Realiza una petición HTTP al servidor de Google para obtener un JSON con la información personal del usuario. Recuerda que siempre debes hacer las peticiones HTTP en un hilo separado del UI Thread.

public fun getInfo():String{   val url= URL("https://www.googleapis.com/oauth2/v3/userinfo")   val conn=url.openConnection() as HttpURLConnection   conn.setRequestProperty("Authorization", String.format("Bearer %s", accessToken))   return=convertStreamToString(conn.inputStream)
}
///////////////////////////////////////////////////////////////////
fun convertStreamToString(input: InputStream):String{ val reader = BufferedReader(InputStreamReader(input)) val sb = StringBuilder() var line: String? try { while (reader.readLine().also { line = it } != null) { sb.append(line).append('\n') } } catch (e: IOException) { e.printStackTrace() } finally { try { input.close() } catch (e: IOException) { e.printStackTrace() } } return sb.toString()}

Conclusión

Ahora puedes soportar el inicio de sesión con Google en todos los dispositivos Android. Recuerda que puedes encontrar más artículos interesantes en el Huawei Developer Forum

--

--