Invio di notifiche push a dispositivi iOS da un server Java

3

Ho un compito apparentemente normale di inviare notifiche push ai dispositivi Apple da un server scritto in Java. Non l'ho mai fatto in passato, quindi sono andato ai tutorial e alla documentazione Apple.

1) La API del provider APN afferma che il protocollo per inviare notifiche push dal server è HTTP / 2. Non sono riuscito a trovare alcun tutorial che descrivesse come farlo (volevo quelli per lo più come un segno che non sono il primo a farlo e forse per i riferimenti agli strumenti / librerie più popolari). Ho trovato diversi tutorial ( tutorial di Ray Wenderlich probabilmente tra i più citati) che insegnano come inviare notifiche push usando il protocollo binario. La maggior parte dei progetti GitHub lo utilizza (ad esempio un "notifica push kit di simulazione da un tutorial di Ray Wenderlich", un popolare " pushmeup " rubino gemma, molto popolare notnoop / java-apns libreria e così via). Ora i documenti Apple hanno una sezione per API di provider binari che afferma che

The legacy binary interface required your provider server to employ the binary API described in this appendix. All developers should migrate their remote notification provider servers to the more capable and more efficient HTTP/2-based API described in APNs Provider API.

Questo sicuramente suona come non dovrei usare l'API binaria per il nuovo sviluppo ... Ancora di più dal momento che l'API binaria richiede l'utilizzo (polling periodico) di un servizio di feedback separato per i token dispositivo "morto" (oppure tu potrebbero essere bloccati, dicono), mentre la nuova API HTTP / 2 fornisce queste informazioni come risposta a ogni singola richiesta, che sembra meno parti mobili.

Come per HTTP / 2, c'è una libreria Java CleverTap / apns-http2 che è anche relativamente popolare, ma usa il client Jetty HTTP / 2, e affinché funzioni un deve iniziare JVM con un jar ALPN sul percorso di classe di avvio e quel jar corrisponde approssimativamente 1-to -1 con le versioni JDK (il che significa che se lo sviluppo utilizza 1.8.0u92 e la produzione utilizza 1.8.0u91, allora dovrebbero essere messi diversi jar). Mi sembra una configurazione molto fragile per me in generale e difficile da applicare nel mio caso (ogni sviluppatore ha il proprio VM + common dev VM + test server + prod) - Non penso valga la pena di bloccare una versione su tutte le macchine e che queste non divergeranno col tempo; tutto quello che so è che tutti usano JDK 8, ma le versioni minori sono fuori dal mio controllo. Questa necessità per il barattolo ALPN sarà il caso fino a quando JDK 9 sarà fuori (e adottato ampiamente), il che significa più di 1 anno, ed è il caso per Jetty e Netty e okhttp3 e credo che qualsiasi libreria Java.

2) Come se non bastasse, ci sono anche due schemi di autenticazione descritti dai documenti Apple: usando un certificato ("vecchio stile") vs usando JWT . L'approccio del certificato è provato e vero, ma dai documenti sembra che il certificato debba essere rigenerato ogni anno mentre i JWT non lo fanno (o per essere più precisi i JWT vengono rigenerati ogni ora automaticamente e così saranno inseriti nell'applicazione e, si spera, non richiederà alcuna azione amministrativa manuale che possa essere dimenticata, ecc.). L'unico problema con JWT per me è che

After you create the token, you must sign it with a private key as described in Creating a Universal Provider Token Signing Key in App Distribution Guide.

Il problema è che non c'è una tale sezione o titolo o qualcosa in quella guida. Forse questo passaggio è molto semplice, ma non avendo alcuna esperienza pratica con la sicurezza iOS in particolare e poca esperienza con la crittografia in generale temo che mi manchi qualcosa qui. Posso chiedere aiuto ai nostri sviluppatori iOS ma non sono nemmeno sicuro che questo approccio sia abbastanza maturo se riesco a trovare zero tutorial di lavoro.

Quindi, le mie domande sono infine (selezionale):

  • Mi manca qualcosa e c'è un modo per seguire le linee guida di Apple e la soluzione è ragionevolmente semplice?
  • Quanto è probabile che il protocollo binario venga terminato "presto"?
  • Dovrei scegliere il protocollo binario o HTTP / 2?
  • Se è quest'ultimo, dovrei continuare a utilizzare JWT o utilizzare un certificato più pratico?
  • Forse la situazione (principalmente con HTTP / 2) è molto migliore in alcune altre lingue / piattaforme server? Potrei anche pensare di avere un servizio separato solo per l'invio di spinte iOS fatte in questo se ciò significa saltare attraverso meno cerchi.

Grazie, mi dispiace per il lungo testo.

    
posta starikoff 27.10.2016 - 00:08
fonte

2 risposte

1

Esiste un modo alternativo di lavorare con HTTP / 2 in Java (alternativa all'ingestione dell'utilizzo del jnk jar aln-boot specifico per JDK): utilizzando il provider SSL nativo che supporta ALPN. Permette di andare senza alp-boot JAR sul percorso di boot completamente. Implementato da netty-tcnative ( github , docs ). È necessario installare Apache Portable Runtime (APR). C'è un sapore legato a OpenSSL (che deve quindi essere installato anche e deve essere della versione 1.0.2 o successiva), diverso per Fedora rispetto a tutte le altre distribuzioni Linux. C'è un sapore collegato staticamente a BoringSSL (fork di OpenSSL con "footprint di codice ridotto").

Non può essere usato con Tomcat (perché AFAIK è una porta parziale di Tomcats tcnative e si scontra con esso) .

La mia impostazione che funziona è risultata essere:

  1. APR installato e OpenSSL.
  2. Specifica la libreria pushy come dipendenza (versione 0.7.3). Ha ricorsivamente portato alpn-api, parti di netty (4.1.1.Final) e altre dipendenze richieste.
  3. specificata netty-tcnative come dipendenza (entrambe le versioni openssl e boringssl hanno funzionato, scelto fino ad ora Boringssl), versione 4.1.1.Finale pure.

La libreria pushy richiede l'utilizzo di un certificato, ma il supporto JWT è sulla strada .

Inoltre, come ha affermato Laiv , GCM (FCM? Firebase?) consente di inviare push a entrambi gli Android e dispositivi iOS. Per quanto ne so, per l'invio a iOS richiede ancora tutte le parti specifiche di Apple, ad esempio il certificato, non sono sicuro del supporto JWT. Sicuramente un'opzione da considerare se non si desidera implementare il supporto per Android e iOS separatamente.

    
risposta data 10.11.2016 - 08:40
fonte
1

Abbiamo implementato diversi server di push e tutti seguono il vecchio tuple "socket-certificate". In Java (1.5 - 1.7) .

Lavorare con i certificati ha alcuni svantaggi. Ad esempio, ne abbiamo bisogno uno per ogni ambiente (test, pro, ecc.). Devi essere metodico nel gestirli o è abbastanza facile finire con il cert sbagliato in pro. O dimenticare il suo rinnovo (anche loro scadono).

In relazione al socket, questo approccio richiede l'apertura di un intervallo specifico di porte nel firewall.

Relativo all'intero protocollo di comunicazione. Ricevi così poche informazioni dopo aver spinto i messaggi. È difficile capire cosa è successo con i messaggi. L'unico modo è recuperare i messaggi dalla coda delle risposte. Una coda in cui gli ordini non sono garantiti. Né quando APNS sta per inserire le risposte su di esso. Potrebbe non succedere affatto.

Rispetto a GCM (messaggio cloud di Google che viene eseguito tramite HTTP), il "socket-cert" di APNS è un problema nel ...

Il mio suggerimento è di concentrarsi sul protocollo HTTP 2 - JWT . Questa è un'implementazione molto comune della sicurezza nelle comunicazioni client-server. Troverai molti più riferimenti su http2 e JWT piuttosto che cercare socket e certificati APNS.

La sicurezza tramite JWT è comunemente implementata in questi giorni. C'è pieno supporto dalla comunità.

Inoltre, se hanno pianificato di abbandonare il supporto all'attuazione attuale, perché persino osare provarlo? Perché spendere tempo e denaro due volte?

Sii preventivo. L'implementazione dell'approccio HTTP2 - JWT ti salverà da ulteriori revisioni e refact del codice. In ogni caso, è un lavoro da fare, quindi è meglio farlo prima.

Correlato alla libreria CleverTap. Beh, nessuno ti impedisce di implementare il tuo cliente! Adatto alle vostre esigenze e necessità.

Questo è stato il nostro caso con il nostro motore attuale. Abbiamo scartato tutte le implementazioni di terze parti e abbiamo creato le nostre. Finora so che continua a funzionare perfettamente ... finché Apple non cede il servizio.

(Se non ci siamo ancora spostati su HTTP2 - JWT è dovuto a tempo e denaro)

Ci sono forse delle alternative. Google Firebase Cloud Message è multipiattaforma. In questo modo puoi inviare messaggi ai dispositivi Android e iOs dallo stesso servizio. Funziona su chiavi HTTP e API (token). Ti suggerisco di dare un'occhiata.

    
risposta data 27.10.2016 - 22:17
fonte

Leggi altre domande sui tag