Plaid permet aux innovateurs de l’espace fintech en leur fournissant un accès aux données financières via une API uniforme. Afin d’aider les utilisateurs finaux à connecter leurs données bancaires aux applications fintech, Plaid a développé Link, un module intégré qui gère la validation des informations d’identification, l’authentification multifacteur et la gestion des erreurs pour chaque banque prise en charge.
Les développeurs Android devaient auparavant ouvrir des URL de lien dans WebViews. Chaque application qui voulait utiliser Link a demandé beaucoup d’efforts aux développeurs et, sans standardisation, il y avait forcément des bugs dans certaines implémentations. Afin d’améliorer l’expérience des développeurs, nous avons récemment publié un SDK rendant la vue Web facile à intégrer dans n’importe quelle application avec quelques lignes de code.
De plus, les vues Web ne sont pas complètement sécurisées pour les utilisateurs finaux qui entrent des informations sensibles dans le flux de liens. Afin de rendre notre SDK aussi sûr que possible, nous l’avons implémenté en utilisant des onglets personnalisés Chrome au lieu de WebViews Android. Dans cet article, nous expliquons pourquoi nous avons pris cette décision et comment nous avons surmonté les problèmes techniques rencontrés en cours de route.
Évaluation de Nos options
En tant que SDK, notre code s’exécute dans les applications d’autres développeurs et, à leur tour, dans leurs processus applicatifs. Pour exécuter l’application web Link dans une vue Web, Javascript doit être activé. Cela ouvre la porte à d’autres applications pour exécuter du code malveillant, comme l’enregistrement de rappels qui tentent d’intercepter les noms d’utilisateur et les mots de passe. De plus, une application malveillante pourrait ouvrir une autre page Web qui imite le flux de liens lors d’une tentative de phishing.
À la recherche d’une solution facile à intégrer pour les développeurs, intuitive pour les utilisateurs finaux et sécurisée, nous avons évalué plusieurs options:
-
créer un flux de liens natif : Comme les flux de liens natifs s’exécuteraient également dans le processus d’une autre application, les développeurs avertis pourraient utiliser reflection pour trouver nos EditTexts d’entrée et enregistrer des rappels d’une manière similaire à Javascript dans une vue Web.
-
création d’une application d’authentification séparée: Cela fournirait une expérience native en bac à sable et serait une expérience idéale pour les utilisateurs finaux; cependant, de nombreux utilisateurs ne voudraient pas télécharger une application supplémentaire sur le Play Store. Cela signifie que nous aurions besoin d’une solution de secours pour les utilisateurs qui refusent de télécharger l’application.
-
ouverture du lien dans une fenêtre de navigateur séparée: Ce serait une solution sécurisée en bac à sable. Presque tous les utilisateurs ont un navigateur installé, mais le passage du contexte d’une application à un navigateur introduirait un retard notable, en particulier sur les appareils bas de gamme.
-
utilisation des onglets personnalisés Chrome: C’est la solution que nous avons choisie, car elle ne présentait aucun des inconvénients mentionnés ci-dessus.
Notre choix: Chrome Custom Tabs
Chrome custom tabs (CCT) fait partie du navigateur Chrome qui s’intègre au framework Android pour permettre aux applications d’ouvrir des sites Web dans un processus léger. CCT s’ouvre plus rapidement qu’un navigateur et, s’il est préchargé via son appel de préchauffage, est potentiellement encore plus rapide qu’une vue Web. Bien qu’il exécute toujours Javascript, il est dans son propre processus, ce qui empêche les applications d’exécuter du code malveillant. De plus, l’interface utilisateur CCT fournit une barre d’action qui affiche l’URL de la page en cours de chargement, ainsi qu’une icône de verrouillage de vérification SSL pour les pages sécurisées. Cela rassure les utilisateurs que la bonne page est affichée.
Bien que tous les utilisateurs n’aient pas installé Chrome, la grande majorité le fait. Pour ceux qui ne le font pas, nous utilisons la méthode de secours du navigateur décrite ci-dessus (option 3); autre que l’ajout d’une ligne de code, nous obtenons le secours gratuitement de CCT. Comme indiqué précédemment, le repli du navigateur n’est pas l’expérience utilisateur idéale en raison de sa latence, mais il maintient le haut niveau de sécurité requis par Plaid.
Au fur et à mesure que nous développions la solution CCT, nous avons rencontré et résolu plusieurs complications:
-
Obtenir des données d’événement
-
Récupération du résultat final
-
Contrôle du processus d’activité CCT &
Obtention des données d’événement
Lorsqu’un utilisateur navigue entre les écrans de Link, une redirection se produit et des données sont fournies aux développeurs dans les paramètres d’URL.
Ces informations de redirection sont précieuses pour les développeurs, car elles les aident à comprendre le comportement des utilisateurs. Avec CCT s’exécutant dans son propre processus et ne fournissant pas de rappel de redirection, ces informations seraient normalement inaccessibles, ce qui rendrait notre SDK sécurisé moins fonctionnel pour les développeurs que leurs implémentations WebView personnalisées.
Pour fournir ces informations à partir du CCT, nous avons plutôt enregistré les événements de redirection sur le serveur dans une banque de données Redis. Lorsque le SDK ouvre Link, il effectue un appel d’amorçage vers nos serveurs, qui fournissent un identifiant de canal par utilisateur que nous avons choisi et une clé secrète. Le SDK crée ensuite un objet de travail à portée d’application, qui interroge le serveur à l’aide d’un flux d’intervalle RX. À chaque appel d’interrogation, nous fournissons au serveur l’ID de canal, la clé secrète et l’UUID du dernier événement (ou null) pour obtenir les derniers événements.
Observable.intervalle (intervalle, unité de temps.SECONDES).subscribeOn (planificateurs.calcul()).observeOn (AndroidSchedulers.mainThread()).Cartes plates (makeNetworkCall()).s'abonner({// Gérer les messages},{// Gérer les erreurs})
Le framework Android peut tuer n’importe quel processus, y compris l’application utilisant le SDK de Plaid. Étant donné que l’objet worker est lié à l’application, cela entraînerait l’arrêt du worker. Si l’utilisateur poursuivait le flux (avec succès ou sans succès), le SDK effectuerait un dernier appel au canal et obtiendrait les événements restants. Les événements ne seraient perdus que si l’utilisateur annulait le flux et que la force tuait l’application.
Récupération du résultat final
Comme pour transmettre des données d’événement aux clients, Link utilise l’URL pour signaler que l’utilisateur a terminé le flux. L’URL pertinente comprend les données nécessaires, telles que la clé publique ou un code d’erreur.
Comme nous ne pouvons pas accéder à l’URL avec CCT, nous avons stocké le résultat final dans Redis avec le même ID de canal. Bien que cela signifie que notre travailleur de sondage saura quand Link est terminé, il n’y aurait aucune garantie que le travailleur serait toujours en vie. Même s’il était vivant, l’utilisateur pourrait devoir attendre le prochain appel d’interrogation pour que le résultat soit livré, ce qui pourrait prendre quelques longues secondes.
Pour nous assurer qu’un résultat est livré en temps opportun, nous utilisons un lien profond pour rouvrir le SDK. Le lien profond est construit à l’aide de l’ID d’application de l’application, qui doit être associé au secret du client et mis en liste blanche sur le tableau de bord du développeur. Ceci, plus le fait qu’une seule application sur un appareil peut avoir le même identifiant d’application, garantit qu’aucune autre application n’intercepte la redirection. L’application Web Link crée ensuite une URI d’intention, qui est déclenchée à la fin du flux de liens.
je ne peux pas le faire, mais je ne peux pas le faire.;
Notre SDK inclut un filtre d’intention pour gérer l’URI, de sorte que l’application se rouvre et passe immédiatement un appel directement au canal.
< filtre d'intention>< action android: nom ="android.intention.action.VOIR" />< catégorie android: nom ="android.intention.catégorie.PAR DÉFAUT" />< catégorie android: nom ="android.intention.catégorie.NAVIGABLE" />< donnéesandroid: hôte="redirection"android:scheme =" plaid" /></ filtre d'intention>
Contrôle CCT
CCT manque d’interfaces pour que l’application puisse:
-
écoutez quand l’utilisateur ferme l’activité
-
détecter lorsque l’utilisateur a cliqué sur l’option « Ouvrir dans le navigateur »
-
forcez-le à se fermer
Nous avons réussi à contourner toutes ces lacunes.
Tout d’abord, pour écouter lorsque l’utilisateur ferme l’activité, nous ouvrons CCT à l’aide de startActivityForResult et lui transmettons un code de requête. Si l’utilisateur ferme CCT à l’aide du X dans le coin supérieur gauche du bouton Retour du système, le rappel onActivityResult est déclenché avec le code de demande que nous avons fourni et un code d’activité de résultat.RESULT_CANCELED. L’intention des données n’inclut aucune information, mais nous pouvons passer un dernier appel au canal pour obtenir les événements restants. Nous les transmettons ensuite à l’application cliente et renvoyons un objet LinkCancellation, signalant que le lien a été fermé intentionnellement par l’utilisateur.
Ensuite, le problème potentiel avec la détection du moment où l’utilisateur a cliqué sur « Ouvrir dans le navigateur » est que l’utilisateur pourrait alors parcourir tout le flux dans une application distincte, à savoir le navigateur. Ce n’est pas un problème pour nous, car les systèmes de sondage et d’intention continuent de fonctionner de la même manière et nous pouvons toujours obtenir les données nécessaires.
Enfin, lorsque l’utilisateur termine le flux avec succès et que l’intention de résultat est déclenchée, le processus CCT reste ouvert et dans la liste des tâches de l’utilisateur. Ce processus fantôme serait non seulement un gaspillage, mais pourrait également être source de confusion pour un utilisateur lorsqu’il appuie sur le bouton système « tâches récentes ». Par conséquent, nous avons besoin d’un moyen de forcer la fermeture du CCT lorsque le flux est terminé.
Pour ce faire, nous avons utilisé le modèle affiché dans la bibliothèque OpenID AppAuth pour Android. Au lieu de gérer le résultat dans l’activité qui ouvre le lien, nous plaçons le filtre d’intention sur une activité distincte. Cette deuxième activité gère toutes les redirections de l’application Web, notamment: complétions réussies, erreurs qui ferment le flux, redirections OAuth ou App-to-App et erreurs système générales. L’activité transmet ensuite les données à l’activité d’ouverture en utilisant une intention avec l’Intention.FLAG_ACTIVITY_SINGLE_TOP et intention.FLAG_ACTIVITY_CLEAR_TOP drapeaux. Utilisés ensemble, ils effacent tout ce qui se trouve sur la pile au-dessus de l’activité d’ouverture, y compris le TDC.
val intent=Intent(activité, LinkActivity::class.java)lorsque (state) {est RedirectState.Chromecomtabscomplete -> {intention.putExtra(LINK_CHROME_CUSTOM_TABS_COMPLETE_REDIRECT, true)intention.putExtra(LINK_RESULT_CODE, state.resultCode)intent.putExtra(LINK_RESULT, state.result)}is RedirectState.UserInitiatedChromeCustomTabsViewClose -> {intent.putExtra(LINK_CHROME_CUSTOM_TABS_USER_CLOSE_REDIRECT, true)}is RedirectState.OAuth -> {intent.putExtra(LINK_OAUTH_REDIRECT, true)intent.putExtra(LINK_OAUTH_STATE_ID, state.oauthStateId)}is RedirectState.RedirectError ->intent.putExtra(LINK_REDIRECT_ERROR, true)}intention.drapeaux = Intention.FLAG_ACTIVITY_SINGLE_TOP ou Intention.FLAG_ACTIVITY_CLEAR_TOPintention de retour
Réflexions finales sur CCT
Afin de fournir une expérience sécurisée en bac à sable non disponible dans les WebViews ou les flux natifs, CCT est une solution viable. Il est facile à intégrer pour les développeurs et offre une meilleure expérience utilisateur que l’ouverture des fenêtres du navigateur grâce à sa nature légère et à sa vitesse.
La nature en bac à sable et l’API limitée de CCT signifient qu’elle n’est pas sans inconvénients. L’écoute des redirections d’URL, l’obtention des résultats finaux et le contrôle du processus CCT nous ont tous obligés à proposer des solutions créatives. Ces solutions reposaient sur une compréhension des fonctionnalités intégrées d’Android, en particulier du framework intent.
Les avantages pour les développeurs et les consommateurs en valaient la peine et nous recommandons d’utiliser CCT dans d’autres applications et SDK pour une intégration rapide et sécurisée. De plus, vous pouvez utiliser les conseils fournis ici pour améliorer l’expérience utilisateur (et développeur).
Si vous souhaitez résoudre des problèmes uniques qui seront utilisés par des milliers de développeurs et des millions de consommateurs, visitez notre page carrières.