Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo puedo restringir el acceso de la API de Endpoints de Google App Engine a sólo mis aplicaciones de Android?

Soy un desarrollador de Android que construye mi primer back-end de Google App Engine (java) para mis aplicaciones. No quiero que nadie más acceda a esta API que no sea mi aplicación. (Planeo usar el motor de aplicaciones para verificar las compras de InApp en mi aplicación de Android). Mis datos no son relevantes para los usuarios, por lo que no quiero que los usuarios puedan acceder a mi API aunque estén conectados con sus cuentas de Google (en dispositivos web o Android).

Seguí los pasos mencionados en – "Especificación de clientes autorizados en el backend API" ( https://developers.google.com/appengine/docs/java/endpoints/auth ) como generar ID de cliente y agregarlos en @Api (clientIds y Públicos), excepto "Agregar un parámetro de usuario", ya que no necesito autenticación de usuario.

A continuación, implementé el motor de aplicaciones y aún así puedo acceder a la API a través del explorador de API ( https://your_app_id.appspot.com/_ah/api/explorer ) (no he añadido ID de cliente API_EXPLORER)

He probado con el APK que se construyó con las librerías de punto final antes de agregar ID de cliente y todavía puede acceder a la API.

  • ¿Es obligatorio añadir un "parámetro de usuario" a todas las API de punto final? Para lograr mi propósito (restringir API sólo a mis aplicaciones de Android).

  • ¿Puedo pasar null como userAccount nombre del cliente de Android e ignorar el valor del parámetro de usuario en el servidor (ya que será nulo)? ¿Garantizará esto que la API sólo es accesible desde mis aplicaciones Android (ya que se genera el ID de cliente para mi nombre de paquete y SHA1 del APK?)

  • ¿Debo usar algo así como una cuenta de servicio para este propósito?

La documentación dice que para Android, los ID de cliente de Android y Web deben agregarse y el público debe ser el mismo que el ID de cliente web. ¿Este acceso abierto a cualquier otro cliente web? Puedo omitir mencionar ID de cliente web y todavía lograr mi propósito?

Apreciar su tiempo y ayuda.

… actualizando con mi investigación posterior …

Hice lo siguiente:

  • Añadido parámetro de usuario a las API en el backend – pero no comprobar el valor nulo. Aún se puede acceder a la API sin pasar credenciales (desde APK de depuración de Android y explorador de API)

  • Entonces lo intenté

    MCredential = GoogleAccountCredential.usingAudience (esto, "server: client_id:" + WEB_CLIENT_ID); MCredential.setSelectedAccountName (null);

Y pasó esta credencial al constructor de la API (como sugerido en algunos otros postes) causó EXCEPCIÓN FATAL. Por lo tanto, no podemos pasar nombre de cuenta nulo.

  • Podría llamar a la API mediante el explorador de API sin OAuth. Pero cuando habilité OAuth, dio error diciendo que este ID de cliente no está permitido! (Todavía no he añadido com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID en client_ids {})

  • Entonces agregué el código para lanzar OAuthRequestException en el backend si el usuario es null. Esto resultó en que el explorador de API obtuvo errores sin OAuth. Funciona con OAuth habilitado después de agregar API_EXPLORER_CLIENT_ID a client_ids)

  • Código añadido para pasar nombre de cuenta de usuario válido (correo electrónico) de mi aplicación de Android. Entonces, puedo acceder a la API sólo con mi versión APK. ¡Incluso el depurador APK obtiene excepciones! – que es lo que esperaba.Por lo tanto, supongo que ninguna otra aplicación de Android será capaz de acceder a esta API.

Por lo tanto, no comprobar el usuario nulo en la API de back-end es una mala idea (como se sugiere en otros mensajes). Es tan bueno como no mencionar cualquier client_ids y no tener param.

La única pregunta que tengo en este momento es: si alguien puede averiguar el WEB_CLIENT_ID del APK, podrán usarlo para construir un cliente web para acceder a mi API (no he mencionado el secreto del cliente en ninguna parte del código. Así que estoy pensando que esto no es posible).


Hice la búsqueda de grupos de Google y Stackoverflow, pero aún no está claro.

  • (Autenticar mi "aplicación" a los puntos finales de la nube de Google, no un "usuario") Autenticar mi "aplicación" a Google Cloud Endpoints no es un "usuario"

  • (¿Cómo protejo mi API que se creó utilizando los puntos finales de Google Cloud?) ¿Cómo protejo mi API que se creó utilizando los puntos finales de Google Cloud?

  • (Restringir el acceso a los puntos finales de la nube de google a la aplicación de Android) Restringir el acceso a los nodos de la nube de google a la aplicación de Android

  • Cambio de token de autenticación de Facebook
  • Plugin de Google no funciona para el proyecto de App Engine - Eclipse Indigo - WindowsXP
  • Integración de aplicaciones de Android Facebook con GAE
  • Google Volley lib con los puntos finales de Appengine autenticados?
  • La importación com.google.api.client no se puede resolver en Eclipse
  • Error de GLS: INVALID_AUDIENCE en los puntos finales de la nube de google
  • Cómo desarrollar el backend de Google App Engine con Android Studio
  • GAE no reconoce la cookie?
  • 5 Solutions collect form web for “¿Cómo puedo restringir el acceso de la API de Endpoints de Google App Engine a sólo mis aplicaciones de Android?”

    Tuve un problema similar, no entre Android y App Engine, sino entre un servidor independiente y App Engine. La manera que manejé era agregar un campo del hash de la firma como parámetro a cada llamada del API. Si la solicitud tenía una firma incorrecta, se negaría.

    Por ejemplo, suponga que el punto final del API es example.com/api/do_thing?param1=foo . Me gustaría hash todo el url, junto con una clave secreta, y luego añadir el resultado de la hash a la solicitud: example.com/api/do_thing?param1=foo&hash=[some long hex value] .

    Luego, en el lado del servidor, primero quitaría el hash de la solicitud de url, luego ejecutaría el hash en todo lo que quedaba. Finalmente, comprueba si el hash calculado coincide con el que se envió con la solicitud y si no lo hace, puede denegar la solicitud.

    Sin embargo, es muy importante que su clave secreta permanezca en secreto. Tienes que tener cuidado con esto en Android porque alguien podría intentar descompilar tu APK.

    Enfrentando el mismo problema que tú! Autenticar Android End point sin cuenta de usuario de Google es simplemente imposible!

    Así que aquí está mi manera de resolver este problema, sin ninguna interacción del usuario (Tal vez no es el derecho, pero que funciona, y usted tiene la autenticación fuerte (SHA1 + cuenta de Google)):

    AQUÍ ESTÁ MI CÓDIGO ANDROID

    Obtener y crear credenciales válidas

      //Get all accounts from my Android Phone String validGoogleAccount = null; Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+ Account[] accounts = AccountManager.get(context).getAccounts(); for (Account account : accounts) { if (emailPattern.matcher(account.name).matches()) { //Just store mail if countain gmail.com if (account.name.toString().contains("gmail.com")&&account.type.toString().contains("com.google")){ validGoogleAccount=account.name.toString(); } } } //Build Credential with valid google account GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this,"server:client_id:301991144702-5qkqclsogd0b4fnkhrja7hppshrvp4kh.apps.googleusercontent.com"); credential.setSelectedAccountName(validGoogleAccount); 

    Utilice esta credencial para realizar llamadas seguras

     Campagneendpoint.Builder endpointBuilder = new Campagneendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential); 

    AQUÍ ESTÁ MI API BACKEND CODE: API Annotation

     @Api( scopes=CONSTANTES.EMAIL_SCOPE, clientIds = {CONSTANTES.ANDROID_CLIENT_ID, CONSTANTES.WEB_CLIENT_ID, com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID}, audiences = {CONSTANTES.ANDROID_AUDIENCE}, name = "campagneendpoint", version = "v1" ) 

    Código de método:

     public Collection<Campagne> getCampagnes(@Named("NumPortable")String NumPortable, User user) throws UnauthorizedException { if (user == null) throw new UnauthorizedException("User is Not Valid"); return CampagneCRUD.getInstance().findCampagne(NumPortable); } 

    Por el momento, sólo funciona en Android (no sé cómo vamos a hacer en IOS ..) ..

    Espero que te ayude !

    Google proporciona formas de hacerlo para Android , web e iOS Los pasos incluyen:

    1. Especificación de un ID de cliente para aplicaciones que desea permitir que realice solicitudes a su API
    2. Agregar un parámetro de usuario a todos los métodos expuestos que se deben proteger mediante autorización.
    3. Generación de la biblioteca de cliente de nuevo para cualquier cliente de Android
    4. Redistribución de su API de backend.
    5. Actualización del archivo jar regenerado en su proyecto de Android para su cliente de Android.

    Estos pasos se describen con claridad en el uso de Auth con endpoints de Google y también en este blog.

    Frente al mismo problema, he aquí el resultado de mi investigación:

    • Se agregó Android cliend id con la huella digital SHA1 en la consola de Google
    • Su uso en la anotación API

    PERO :

    • Si no agrego el parámetro del usuario a los métodos: la comprobación sobre la identificación del cliente de la aplicación de Androide no trabaja

    • Si agrego el parámetro USER pero no pido al usuario que elija su cuenta de google para crear la credencial … también no funciona …

    Conclusión: Parece ser obligatorio conectar una cuenta de usuario para el cheque sobre el ID de cliente de la aplicación que se va a ejecutar … Realmente no entiendo por qué porque no existe ningún enlace entre los 2 procesos

    Acceder a este sitio

    Elija su proyecto, vaya a la sección de credenciales

    Crear una nueva clave de api

    Crear una nueva clave android

    Haga clic en "Editar aplicaciones Android permitidas" e ingrese su clave SHA1; El nombre del paquete de Android

    Déjame saber si esto soluciona los problemas.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.