crear - ¿Cómo restrinjo el acceso API de Google App Engine Endpoints solo a mis aplicaciones de Android?
crear aplicacion con google app engine (5)
Enfrentando el mismo problema que tú! ¡Autenticar el punto final de Android sin la 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 sea el correcto, pero eso funciona, y usted tiene una autenticación fuerte (SHA1 + Cuenta de Google)):
AQUÍ ES MI CÓDIGO ANDROID
Obtenga y cree una credencial válida
//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);
Use esta credencial para llamadas seguras
Campagneendpoint.Builder endpointBuilder = new Campagneendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), credential);
AQUÍ ES MI CÓDIGO BACKEND API : Anotación API
@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, solo funciona en Android (no sé cómo vamos a hacer en iOS ...)
Espero que te ayude !
Soy un desarrollador de Android que desarrolla 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, incluso si han iniciado sesión con sus cuentas de Google (en la web o dispositivos Android).
Seguí los pasos mencionados en "Especificar 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 audiencias) excepto "Agregar un parámetro de usuario", ya que no necesito autenticación de usuario.
Luego implementé el motor de aplicaciones y todavía puedo acceder a la API a través del explorador de API ( https://your_app_id.appspot.com/_ah/api/explorer ) (no he agregado el ID de cliente de API_EXPLORER)
Probé con el APK que se creó con las librerías de punto final antes de agregar ID de cliente y todavía puedo acceder a la API.
¿Es obligatorio agregar un "parámetro de usuario" a todas las API de punto final? para lograr mi propósito (restringir API a solo mis aplicaciones de Android).
¿Puedo pasar null como nombre de cuenta de usuario del cliente de Android e ignorar el valor del parámetro de usuario en el servidor (ya que será nulo)? ¿Esto garantizará que solo se pueda acceder a la API desde mis aplicaciones de Android (ya que la ID del cliente se genera 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, se deben agregar las ID de los clientes Android y Web y la audiencia debe ser la misma que la ID del cliente web. ¿Esto abre el acceso a cualquier otro cliente web? ¿puedo omitir mencionar el ID del cliente web y aun así lograr mi propósito?
Aprecia tu tiempo y ayuda.
...... actualizando con mi investigación adicional ...
Hice lo siguiente:
Se agregó un parámetro de usuario a las API en el back-end, pero no se verificó el valor nulo. Aún se puede acceder a la API sin pasar ninguna credencial (de Android depurador APK y API explorer)
Entonces, lo intenté
mCredential = GoogleAccountCredential.usingAudience (esto, "server: client_id:" + WEB_CLIENT_ID); mCredential.setSelectedAccountName (null);
y pasó esta credencial al generador de API (como se sugiere en algunas otras publicaciones) Causó EXCEPCIÓN FATAL. Por lo tanto, no podemos pasar un nombre de cuenta nulo.
Podría llamar a la API usando el explorador API sin OAuth. Pero cuando habilité OAuth, me dio un error al decir que esta identificación de cliente no está permitida. (Todavía no agregué com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID en client_ids {})
Luego agregué código para arrojar OAuthRequestException en el back-end si el usuario es nulo. Esto resultó en que API explorer recibiera errores sin OAuth. Funciona con OAuth habilitado después de agregar API_EXPLORER_CLIENT_ID a client_ids)
Se agregó un código para pasar un nombre de cuenta de usuario (correo electrónico) válido desde mi aplicación de Android. Luego, puedo acceder a la API solo con mi versión APK. ¡Incluso el APK de depuración obtiene excepciones! - que es lo que esperaba ... Así que, supongo que ninguna otra aplicación de Android podrá acceder a esta API.
Por lo tanto, no buscar un usuario nulo en la API de back-end es una mala idea (como se sugiere en otras publicaciones). Es tan bueno como no mencionar ningún client_ids y no tener User param.
La única pregunta que tengo en este momento es: si alguien puede descifrar el ID_CLIENTE_LOCAL del APK, ¿podrán usarlo para construir un cliente web para acceder a mi API? (No he mencionado el secreto del cliente en ningún lugar del código). Así que estoy pensando que esto no es posible).
Busqué grupos de Google y Stackoverflow, pero aún no está claro.
(Autentique mi "aplicación" a los puntos finales de la nube de Google, no a un "usuario") Autentique mi "aplicación" a Google Cloud Endpoints, no a un "usuario"
(¿Cómo protejo mi API creada con Google Cloud Endpoints?) ¿Cómo protejo mi API creada con Google Cloud Endpoints?
(Restrinja el acceso a los puntos finales de Google Cloud a la aplicación de Android) Restrinja el acceso a los puntos finales de Google Cloud a la aplicación de Android
Enfrentando el mismo problema, aquí están el resultado de mi investigación:
- Se agregó ID de usuario de Android con huella digital SHA1 en la consola de Google
- Uso de él en la anotación API
PERO :
Si no agrego el parámetro de usuario a los métodos: el cheque sobre la identificación del cliente de la aplicación Android no funciona
Si agrego el parámetro USER pero no le pido al usuario que elija su cuenta de google para crear la credencial ... tampoco funciona ...
Conclusión: parece ser obligatorio conectar una cuenta de usuario para el control de la id del cliente de la aplicación que se ejecutará ... Realmente no entiendo por qué, porque no existe un vínculo entre los 2 procesos
Google proporciona formas de hacer esto para Android
, web
e iOS
Los pasos implican:
- Especificando un ID de cliente para las aplicaciones que desea permitir para realizar solicitudes a su API
- Agregar un parámetro de usuario a todos los métodos expuestos para que estén protegidos por autorización.
- Generando la biblioteca del cliente nuevamente para cualquier cliente de Android
- Volver a implementar su API back-end.
- Actualizando el archivo jar regenerado a su proyecto Android para su cliente Android.
Estos pasos están detallados en Google Auth Using Endpoints y también en este blog
Tuve un problema similar, no entre Android y App Engine, sino entre un servidor independiente y App Engine. La forma en que lo manejé fue agregar un campo de hash de firma como parámetro para cada llamada API. Si la solicitud tenía una firma incorrecta, sería denegada.
Por ejemplo, supongamos que su punto final API es example.com/api/do_thing?param1=foo
. Quitaría la URL completa, junto con una clave secreta, y luego anexaría el resultado del hash a la solicitud: example.com/api/do_thing?param1=foo&hash=[some long hex value]
.
Luego, en el lado del servidor, primero quitaba el hash de la solicitud de url, luego ejecutaba el hash en todo lo que quedaba. Finalmente, compruebe si el hash calculado coincide con el que se envió con la solicitud y, en caso contrario, puede denegar la solicitud.
Sin embargo, es muy importante que su clave secreta permanezca en secreto. Debes tener cuidado con esto en Android porque alguien podría intentar descompilar tu APK.
Elija su proyecto, vaya a la sección de credenciales
Crea una nueva clave api
Crea una nueva clave de Android
Haga clic en "Editar aplicaciones de Android permitidas" e ingrese su clave SHA1; su nombre de paquete de Android
Avíseme si esto resuelve los problemas.