L'applicazione è un client Android per un servizio remoto sul quale tutti gli utenti dispongono di account e possono effettuare acquisti di articoli non di consumo. Ogni acquisto è legato all'account su cui sono stati acquistati. Lo schema di acquisto corrente è il seguente:
- Il cliente avvia l'acquisto con il servizio di fatturazione in-app di Google Play. La richiesta di acquisto contiene il payload che identifica in modo univoco l'account.
- Una volta completato l'acquisto, il cliente recupera i dati di acquisto che contengono il carico utile e il token di acquisto. Inoltre ha una firma per i dati ricevuti che al momento non è stato controllato.
- Il client invia il token di acquisto al server. A questo punto deve essere autenticato.
- Il server riceve il token di acquisto. Il server esegue l'autenticazione con il servizio Google Play utilizzando la sua chiave dell'account di servizio e riceve i dati di acquisto per il token indicato. I dati contengono il carico utile originale e le informazioni riguardanti l'acquisto.
- Il server convalida i dati di acquisto: si verifica che il payload corrisponda all'id utente attualmente connesso, che l'acquisto non sia ancora stato consumato e che sia stato pagato con successo.
- Se la verifica ha esito positivo, viene contrassegnato che il cliente ha acquistato il prodotto sul server e il client riceve una conferma, altrimenti il client riceve un rifiuto.
Cosa potrebbe andare storto con questo schema? Ad esempio, mi preoccupa che la firma non venga utilizzata da nessuna parte. Tuttavia, non vedo quale uso ci sia se il server riceve i dati direttamente da Google Play. Nel peggiore dei casi, può ricevere un token errato, ma il payload contiene l'id utente, quindi l'acquisto verrà rifiutato se è stato creato per un altro account. Anche l'invio dello stesso token due volte è inutile poiché il prodotto non è consumabile: è stato acquistato o meno. Ma forse mi manca qualcosa qui o c'è qualche altro difetto che non vedo?