Cómo agregar la verificación de licencia en el servidor a tu app
Organiza tus páginas con colecciones
Guarda y categoriza el contenido según tus preferencias.
Cuando verificas si el usuario compró o descargó una copia legítima de tu app de Google Play Store, es mejor realizar la verificación de la licencia en un servidor que puedas controlar.
En esta guía, se presenta un proceso paso a paso para completar la verificación de la licencia desde el servidor y algunas de las prácticas recomendadas que se relacionan con esta verificación.
Descripción general del proceso
En la figura 1, se muestra cómo se transfiere la información entre tu aplicación, Google Play y tu servidor privado:
Figura 1: Flujo de datos entre tu app y Google Play, y luego entre tu app y tu servidor privado
Tu app envía una solicitud a Google Play con el objetivo de averiguar si un usuario en particular compró o descargó una copia legítima de tu app.
Google Play responde mediante el envío de un objeto de datos de respuesta, un objeto de tipo ResponseData, a tu app. Este objeto se compone de información firmada que indica si el usuario compró o descargó una copia legítima de tu app.
Tu app realiza una solicitud a un servidor privado que tú controlas y verifica el contenido de los datos de respuesta.
El servidor responde enviándole a tu app un estado que indica si el usuario efectivamente compró o descargó una copia legítima. Si el servidor proporciona un mensaje de "éxito", verifica la respuesta y luego otorga al usuario acceso a los recursos que requieren una licencia.
Debido a que los datos de respuesta fueron firmados por Google Play y luego se verificaron en tu servidor, no hay forma de modificar el objeto en el dispositivo que ejecuta tu app. Si la app depende del servidor y pone recursos a disposición de usuarios legítimos, estará mucho más protegida contra usuarios no autorizados.
En las siguientes secciones, se incluyen consideraciones adicionales que se deben tener en cuenta al realizar la verificación de licencia en el servidor.
Protección contra ataques de repetición
Después de recibir una respuesta de Google Play relacionada con el estado de la licencia del usuario, es posible que el usuario copie los datos de respuesta y los use varias veces o que se los dé a otros usuarios que podrían falsificar sus propias solicitudes en el servidor privado de tu aplicación. Este tipo de acción se conoce como ataque de repetición.
Para reducir la probabilidad de que los usuarios realicen ataques de repetición correctamente, toma las siguientes medidas antes de enviar una solicitud al servidor de tu app:
Verifica la marca de tiempo que se incluye en los datos de respuesta y asegúrate de que Google Play haya generado la respuesta recientemente.
Realiza una limitación de velocidad en la solicitud de tu servidor, como una retirada exponencial, para reducir la cantidad de veces que tu app intenta enviar los mismos datos de respuesta al servidor de tu app.
Antes de verificar el contenido de los datos de respuesta de Google Play en tu servidor privado, haz una solicitud inicial basada en autenticación a tu servidor privado. En esta primera solicitud, envía las credenciales de usuario a tu servidor y haz que este responda con una instancia (un número que se usa una sola vez). Luego, puedes incluir esta instancia en tu próxima solicitud a tu servidor privado para solicitar datos de verificación de licencia. Si quieres obtener detalles sobre cómo elegir un buen valor para la instancia, consulta la sección sobre cómo generar un valor adecuado de instancia.
Cómo generar un valor de instancia adecuado
Usa una de las siguientes técnicas para crear un valor de instancia que sea difícil de adivinar:
Genera un valor hash basado en el ID del usuario.
Genera un valor aleatorio para cada usuario. Almacena ese valor aleatorio en el servidor de tu app como parte de los atributos de un usuario determinado.
Verifica los datos de respuesta de tu servidor
Cuando revises los datos de respuesta que el servidor de tu app envía a tu aplicación, asegúrate de que la respuesta de la biblioteca de verificación de licencias no esté falsificada. Verifica la firma incluida en los datos de respuesta del servidor de apps comparándola con la clave que tu app recibió de Google Play en un paso anterior.
También vale la pena recordar que el bloque específico de la biblioteca de verificación de licencias (LVL) es la única parte que se firma. Por lo tanto, es la única parte de los datos de respuesta de tu servidor de apps en la que tu app debe confiar.
El contenido y las muestras de código que aparecen en esta página están sujetas a las licencias que se describen en la Licencia de Contenido. Java y OpenJDK son marcas registradas de Oracle o sus afiliados.
Última actualización: 2025-07-27 (UTC)
[[["Fácil de comprender","easyToUnderstand","thumb-up"],["Resolvió mi problema","solvedMyProblem","thumb-up"],["Otro","otherUp","thumb-up"]],[["Falta la información que necesito","missingTheInformationINeed","thumb-down"],["Muy complicado o demasiados pasos","tooComplicatedTooManySteps","thumb-down"],["Desactualizado","outOfDate","thumb-down"],["Problema de traducción","translationIssue","thumb-down"],["Problema con las muestras o los códigos","samplesCodeIssue","thumb-down"],["Otro","otherDown","thumb-down"]],["Última actualización: 2025-07-27 (UTC)"],[],[],null,["# Adding Server-Side License Verification to Your App\n\nWhen verifying that the user has purchased or downloaded a legitimate copy of\nyour app from the Google Play Store, it's best to perform the license\nverification check on a server that you control.\n\nThis guide presents a step-by-step process for completing server-side license\nverification and presents some best practices related to performing this check.\n\nProcess overview\n----------------\n\nFigure 1 shows how information is transferred between your app, Google Play, and\nyour private server: \n**Figure 1.** Flow of data between your app and Google Play, then between your app and your private server\n\n1. Your app makes a request to Google Play, inquiring about whether a particular user has purchased or downloaded a legitimate copy of your app.\n2. Google Play responds by sending a *response data object* , an object of type [`ResponseData`](/google/play/licensing/licensing-reference#lvl-summary), to your app. This object is a signed piece of information that states whether the user has purchased or downloaded a legitimate copy of your app.\n3. Your app makes a request to a private server that you control, verifying the contents of the response data.\n4. The server responds by sending a status to your app, indicating whether the user has indeed purchased or downloaded a legitimate copy of your app. If the server provides a \"success\" message, [verify the\n response](#verify-app-server-response) and then grant the user access to the resources that require a license.\n\nBecause the response data is signed by Google Play, then checked on your\nserver, there's no way to modify the object on the device running your app. If\nyour app relies on the server and makes resources available only to legitimate\nusers, your app is substantially more protected against unauthorized users.\n\nThe following sections provide additional considerations to keep in mind when\nperforming server-side license verification.\n\nSafeguard against replay attacks\n--------------------------------\n\nAfter receiving a response from Google Play regarding the user's license status,\nit's possible for the user to copy the response data and use it multiple times,\nor give it to other users who could then forge their own requests to your app's\nprivate server. This sort of action is known as a *replay attack*.\n\nTo reduce the likelihood of users performing replay attacks successfully, take\nthe following measures before sending a request to your app's server:\n\n- Check the timestamp that's included in the response data, making sure that\n Google Play generated the response recently.\n\n | **Note:** You can increase the allowed difference between the response data's timestamp and the current time based on how long users should be able to interact with license-bound resources after they deactivate their license.\n- Perform rate-limiting on your server request, such as exponential backoff, to\n reduce the number of times that your app attempts to send the same response data\n to your app's server.\n\n | **Caution:** To preserve a good user experience in cases where a user interacts with your app on a variety of devices, be careful if you add rate-limiting based on number of devices.\n- Before verifying the contents of Google Play's response data on your private\n server, make an initial, authentication-based request to your private server. In\n this first request, send user credentials to your server, and have your server\n then respond with a *nonce* , or a number that is used only once. You can then\n include this nonce in your next request to your private server, asking for\n license verification data. For details on how to choose a good value for the\n nonce, see the [generate a suitable nonce value](#generate-nonce) section.\n\n | **Note:** Include a user ID field in both the nonce request and the license verification request. Your app's server can then compare the fields' values from the two requests and make sure they match.\n\n### Generate a suitable nonce value\n\nUse one of the following techniques to create a nonce value that's difficult to\nguess:\n\n- Generate a hash value based on the user's ID.\n- Generate a random value on a per-user basis. Store this random value on your app's server as part of a given user's attributes.\n\nVerify response data from your server\n-------------------------------------\n\nWhen reviewing response data that your app's server sends to your app, make sure\nthat the License Verification Library response isn't forged. Verify the\nsignature that's included in the app server's response data by comparing it\nwith the key that your app received from Google Play in a previous step.\n\nIt's also worth remembering that the block specific to the License Verification\nLibrary (LVL) is the only part that's signed. Therefore, it's the only part of\nyour app server's response data that your app should trust."]]