APN o Apple Push Notifications es el sistema a través de cuál Apple permite enviar las notificaciones que aparecen en sus dispositivos: alertas, banners, etc.

Para hacerlo posible, Apple ha creado un sistema basado en peticiones HTTPS a través del cual podemos hacer llegar información de aviso a los distintos dispositivos que tengan nuestra app instalada siempre y cuando lo hayan autorizado previamente.

En esta compacta guía dividida en dos posts, intentare hacer un resumen de los pasos que debemos seguir para conseguir exitosamente generarlas, enviarlas y mostrarlas de forma rápida y eficaz, entendiendo todos los conceptos necesarios. Es importante dejar constancia de que la guía se ha confeccionado en su mayoría a partir de la documentación de apple diponible en https://developer.apple.com/documentation/.

 

 

Overview

 

Para entender bien lo que vamos a hacer, empecemos desglosando por pasos el camino que sigue una notificación desde nuestro servidor de backend, hasta el dispositivo final.

  1. Ocurre un evento. Nuestro servidor genera una petición de notificación con la información que queremos enviar a nuestro dispositivo destino. Entre los metadatos que debe contener la petición, uno de ellos debe ser el token del dispositivo de destino. Este token se debe extraer previamente y ser enviado al backend desde la aplicación instalada en el dispositivo (en el próximo post veremos como hacerlo).

  2. Nuestro servidor de backend establece una conexión segura con el servidor de Apple dedicado a enviar las notificaciones a los dispositivos finales (de ahora en adelante le llamaremos servidor APN) y le envía la petición.

  3. Finalmente el servidor APN hace llegar la notificación a destino y la petición genera una notificación que muestra la información deseada al usuario. En caso de no encontrarse disponible, almacena la notificación que se entrega en la mayor brevedad posible.

 

 

 

Seguridad de la conexión con el servidor APN

 

Para conectarse al servidor APN de forma segura Apple nos da dos opciones de configuración con sus pros y contras:

  • Conexión mediante tokens: Esta primera opción consiste en hacer las peticiones con un token en la cabecera de la petición HTTP. Dicho token (conocido como Bearer token) nos provee de una seguridad statelessy la posibilidad de caducar el token en cualquier momento. Es más rápida que la opción mediante certificados ya que evita todo el proceso de intercambio de claves, aunque las peticiones son mas pesadas por incluír el token en cada una de ellas.

  • Conexión mediante certificados: Este tipo de conexión exige una conexión HTTP/2 sobre TLS y tener instalados los certificados raíz que usa Apple que se encuentran en el siguiente enlace: certificado raíz de GeoTrust (Hablé de certificados en este post)

 

 

Conexión mediante tokens

 

Además de su velocidad, mas rápida que el sistema mediante certificados, esta opción tiene otras ventajas importantes: 

  • podemos conectar desde distintos servidores con un mismo token.

  • podemos enviar peticiones de notificaciones a distintas apps que hayamos desarrollado con un mismo token.

Las principales contrapartidas son:

  • Cada petición HTTP es mas pesada, ya que cada una de ellas debe contener el Bearer Token en su cabecera.

  • Cada hora, como mínimo, hay que firmar (generar) los tokens con una clave que nos proporciona Apple. Aunque lo recomendable es generar el token en el momento de generación de la petición, lógicamente. (Hable de las firmas digitales y sistemas de cripografía asimétrica en este post)

 

 

¿Cómo obtener la clave con la que firmar los tokens?

 

Para generar la clave con la que firmaremos los tokens, es decir, la clave que usaremos para generarlos ( ya que si no están firmados no sirven ) debemos ir a nuestra cuenta de desarrollador  en https://developer.apple.com/.

Primero de todo le decimos que queremos generar una clave: Create a key

 

 

Finalmente hay una última ventana que nos pide confirmación y nos permite descargar la clave.Ahora ya tenemos la clave con la que firmar los tokens. Veamos como usarla:

Los tokens que deben ir en cada una de las peticiones y siguen la especificación JWT o JSON Web Token. Siguiendo dicha especificación, debemos generar un token con 4 campos: alg, kid, isse e iat.

 

CAMPO CONTENIDO
alg Este campo debe contener ‘ES256’ que es el algoritmo de firmado o cifrado del token
kid La clave que hemos obtenido de apple desde la cuenta de desarrollador
iss La clave de desarrollador. Es un numero que nos asigna apple como equipo de desarrollo. Se puede encontrar también en la cuenta de desarrollador.
iat El la hora en que se generó el token expresado en segundos UTC en Epoch, es decir desde el 1 de enero de 1970 00:00 GMT (https://espanol.epochconverter.com)

 

El objeto JSON a partir del cual generaremos el JWT, viene a ser algo como:

 

{

   “alg” : “ES256”,

   “kid” : “ABC123DEFG”

}

{

   “iss”: “DEF123GHIJ”,

   “iat”: 1437179036

}

 

Este objeto debe ser codificado en ES256.

Con el fin de generar dicho token disponemos de varias librerías en distintos lenguajes en que nos resultará tan fácil como indicar cada uno de los campos -cabeceras y claims- para obtener el token. Véase: https://jwt.io/.

El resultado debe ser algo como lo siguiente:

 

bearer eyAia2lkIjogIjhZTDNHM1JSWDciIH0.eyAiaXNzIjogIkM4Nk5WOUpYM0QiLCAiaWF0I

           jogIjE0NTkxNDM1ODA2NTAiIH0.MEYCIQDzqyahmH1rz1s-LFNkylXEa2lZ_aOCX4daxxTZkVEGzwIhALvkClnx5m5eAT6

           Lxw7LZtEQcH6JENhJTMArwLf3sXwi

 

Pues bien, ese token debe ir en cada una de las peticiones que hagamos al servidor APN. Se recomienda generar generar un nuevo token cada 20 minutos y el servidor no acepta los que hayan superado 1hora.

 

 

Conexión mediante certificados

El sistema de certificados es algo mas limitado y engorroso en cuanto a su instalación y funcionamiento y tiene algunas limitaciones ya que cada certificado es válido para enviar notificaciones a una sola app y sus servicios background VoIP asociados. Es decir, para apps distintas debemos tener certificados distintos. Su validez es de un año. Y a partir de entonces hay que renovarlo o bien generar uno nuevo.

 

Para obtener un certificado, igual que con el key, debemos hacerlo en https://developer.apple.com/. En el apartado de certificados, le damos a crear un nuevo certificado:

 

 

 

Cómo podemos ver en la imagen, tenemos varias opciones de certificados para APN: 2 para entorno de pruebas y 2 para producción. Selecionamos la que necesitemos.

En la siguiente página nos pide que seleccionemos la ID de Apple para nuestra aplicación. Seleccionamos la que corresponda. Entonces de repente nos pide un un CSR  ¡¿?! 

 

 

¿Que es un CSR?

 

Un CSR o Certificate Signing Request es el certificado sin firmar. Es decir que tenemos que generar un certificado sin firmar con nuestros datos y apple lo firmará con su clave privada para certificar que ese certificado es válido y confiable.

Podemos ver cómo se genera un CSR aquí.

Finalmente seleccionamos el CSR que tendremos que haber generado previamente y nos lo devolverá firmado. Por fin tenemos nuestro certificado. Solo habrá que instalarlo debidamente en nuestro servidor para realizar el correspondiente intercambio de claves, en su momento.

 


NOTA IMPORTANTE:

Debemos mantener el CSR ya que contiene nuestra CLAVE PRIVADA Y NUESTRA CLAVE PÚBLICA mientras que el CERTIFICADO FIRMADO RESULTANTE contiene LA CLAVE PÚBLICA con la que APN codificará las comunicaciones con nosotros.

Ambos deben ser instalados en el servidor backend pero el CSR debe tener restringido el acceso solo a usuarios CON PRIVILEGIOS.


 

En el próximo post veremos como se deben enviar las peticiones https al servidor APN y como preparar nuestra aplicación para que las muestre correctamente.

 

¡Hasta pronto!