L'intégration de l'authentification OAuth dans les extensions de navigateur est une tâche complexe mais essentielle, particulièrement pour ceux qui souhaitent offrir à leurs utilisateurs une expérience fluide tout en accédant à des services externes, comme Google. Lorsqu'on configure OAuth, il est crucial de comprendre les subtilités des différents types d'application et de choisir la méthode qui correspond le mieux aux besoins du projet. Google propose plusieurs options pour configurer un client OAuth, chacune ayant ses propres caractéristiques et avantages.

Lorsque vous créez un identifiant client OAuth dans le tableau de bord Google Cloud, il existe deux types d'applications que vous pouvez choisir : "Extension Chrome" et "Application Web". Bien que les deux puissent être utilisées pour une extension de navigateur, elles diffèrent dans la manière dont elles gèrent l'authentification et les tokens.

  1. Extension Chrome : L'utilisation du champ oauth2 dans le manifeste de l'extension permet d'authentifier un utilisateur via le profil Chrome actif à l'aide de la méthode getAuthToken(). Cela signifie que l'authentification se fait directement dans le profil Google Chrome, ce qui peut poser des problèmes de confidentialité si l'utilisateur ne souhaite pas que son profil soit utilisé pour d'autres applications ou extensions.

  2. Application Web : Dans cette configuration, la méthode launchWebAuthFlow() est utilisée, permettant une authentification distincte de celle du profil Google Chrome. Cette méthode est plus flexible et permet d'éviter les conflits potentiels si l'utilisateur ne veut pas que l'extension accède à son profil Chrome.

Ces choix doivent être bien compris avant de commencer à configurer OAuth, car ils influencent non seulement la manière dont l'utilisateur interagit avec l'extension, mais aussi la sécurité et la confidentialité des données traitées.

Une fois l'identifiant client créé, Google vous fournit un fichier JSON contenant des informations essentielles telles que le client_id, le project_id, ainsi que les URL nécessaires pour l'authentification et la récupération du token. Ce fichier doit être intégré dans le code de l'extension afin de permettre l'authentification via OAuth.

Exemple de fichier client_secret.json :

json
{ "installed": { "client_id": "xxxxx.apps.googleusercontent.com", "project_id": "browser-extension-explorer", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs" } }

Le processus de configuration d'OAuth peut sembler confus, mais il existe des ressources qui facilitent cette tâche. Par exemple, le site officiel de Google et d'autres blogs spécialisés offrent des guides détaillés pour intégrer OAuth dans les extensions Chrome et autres applications web. Voici quelques ressources utiles :

Il est également important de pratiquer avec du code réel pour mieux comprendre les mécanismes en jeu. L'extension compagnon du livre offre des exemples de code OAuth fonctionnels qui peuvent être utilisés comme point de départ. Pour les développeurs, le fait d’expérimenter avec des exemples concrets est indispensable pour saisir les nuances du processus d’authentification.

Prenons l'exemple d'un flux OAuth avec Google utilisant getAuthToken(). L'extension demandera l'accès aux informations d'identité de l'utilisateur, notamment l'email et l'identifiant Google, ce qui permet d’interagir avec l'API d'identité de Google. Après une authentification réussie, l'extension peut récupérer les informations de profil de l'utilisateur à l'aide de la méthode chrome.identity.getProfileUserInfo().

Voici un exemple de code pour configurer l'extension dans le manifeste et dans le fichier JavaScript :

Exemple de manifeste (manifest.json) :

json
{
"name": "Google OAuth Example", "version": "0.0.1", "manifest_version": 3, "action": {}, "background": { "service_worker": "background.js", "type": "module" }, "permissions": ["identity", "identity.email"], "oauth2": { "client_id": "xxxxx.apps.googleusercontent.com", "scopes": [ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile" ] } }

Exemple de fichier JavaScript (background.js) :

javascript
chrome.action.onClicked.addListener(() => {
chrome.identity.getAuthToken({ interactive: true }, (token) => { if (token) { chrome.identity.getProfileUserInfo({ accountStatus: "ANY" }, (info) => console.log(info)); } }); });

L'extension fonctionne de manière transparente pour l'utilisateur : lors du clic sur l'icône de l'extension, un flux OAuth s'ouvre, demandant l'autorisation d'accéder aux informations nécessaires. Une fois l'authentification réussie, le jeton d'accès est stocké et peut être utilisé pour récupérer les informations du profil de l'utilisateur.

En revanche, un flux basé sur OpenID avec la méthode launchWebAuthFlow() nécessite une configuration un peu plus complexe, notamment le besoin de générer une URL de redirection et de traiter le retour des informations via un JSON Web Token (JWT). Bien que cette approche offre plus de contrôle et de sécurité, elle demande également un investissement en termes de configuration.

Il est donc essentiel de bien choisir la méthode d'authentification en fonction des besoins spécifiques de l'application, qu'il s'agisse de la simplicité d'une extension Chrome ou de la flexibilité d'une application Web.

Le principal aspect à retenir dans le cadre de l'intégration OAuth dans une extension de navigateur est que cette configuration, bien que techniquement exigeante, permet d'offrir une expérience utilisateur sécurisée et fluide. La clé réside dans la compréhension des différentes options et dans la mise en place d'un flux d'authentification qui soit à la fois simple et sécurisé.

Comment fonctionne l'API declarativeNetRequest dans les extensions de navigateurs modernes ?

L'API declarativeNetRequest (DNR) représente une évolution majeure dans la manière dont les navigateurs gèrent les requêtes réseau des extensions. Contrairement à l'ancienne API webRequest qui utilisait des gestionnaires JavaScript pouvant bloquer ou modifier les requêtes en temps réel, DNR repose sur un modèle déclaratif. Ce dernier est implémenté directement par le navigateur, ce qui permet d'améliorer la performance et la sécurité. Plutôt que d’intervenir via du code exécuté à chaque requête, les règles sont fournies sous forme d’objets JSON définissant les conditions et actions à appliquer. Cela simplifie le traitement et évite les ralentissements causés par des scripts bloquants.

L’API DNR s’utilise avec différentes permissions adaptées à la portée d’action de l’extension. La permission de base « declarativeNetRequest » permet de définir des règles mais nécessite toujours l’autorisation d’accès aux hôtes concernés. L’option « declarativeNetRequestWithHostAccess » offre une portée plus large, autorisant le blocage ou la mise à niveau des requêtes sans requérir ces permissions d’hôtes, sauf pour les opérations de redirection ou modification d’en-têtes qui restent soumises à des autorisations spécifiques. Enfin, « declarativeNetRequestFeedback » ajoute des capacités d’analyse des règles appliquées, permettant à l’extension de recevoir des retours détaillés sur leur exécution.

Les règles DNR sont constituées d’objets JSON uniques, chaque règle portant un identifiant unique et une condition déterminant son champ d’application (domaines, types de ressources, onglets, etc.). L’action associée peut bloquer, rediriger, autoriser, modifier des en-têtes ou changer le protocole des requêtes. Ces règles peuvent être statiques, définies dans des fichiers JSON embarqués dans l’extension, ou dynamiques, créées, modifiées et supprimées en cours d’exécution par le code de l’extension.

Les règles sont aussi classifiées en « sûres » et « non sûres ». Les règles dites sûres incluent les actions bloquantes ou autorisantes simples, tandis que les règles non sûres impliquent des modifications plus complexes comme la redirection ou la modification des en-têtes HTTP. Cette distinction est essentielle car elle impacte les quotas d’utilisation (les règles sûres bénéficient d’un quota beaucoup plus élevé) et les processus de validation lors des mises à jour d’extensions.

L’exemple d’une extension simple bloque les images sur les sites wikipedia.org et wikimedia.org en activant ou désactivant un ensemble statique de règles. Le comportement se pilote par un bouton dans la barre d’outils, illustrant la gestion dynamique des règles statiques. En parallèle, un autre exemple montre comment implémenter une redirection dynamique des images vers une autre URL, démontrant la flexibilité et la puissance de l’API.

Un aspect technique important est la génération automatique d’un fichier binaire _metadata local, qui sert au navigateur pour indexer les règles actives. Ce fichier ne doit pas être intégré dans les systèmes de gestion de versions ni être déployé en production, soulignant la séparation entre le code source et les données générées à l’exécution.

Au-delà des exemples pratiques, il faut comprendre que cette évolution reflète un changement de paradigme vers un modèle plus sécurisé et performant pour la gestion des requêtes réseau dans les navigateurs modernes. Les restrictions imposées par les navigateurs Chromium sur le blocage direct via JavaScript ont poussé à cette refonte, tandis que Firefox conserve une compatibilité avec l’ancienne API dans Manifest V3. Le modèle déclaratif facilite la prévisibilité, réduit les risques de vulnérabilités dues à des scripts complexes, et améliore l’expérience utilisateur par une meilleure réactivité.

Il est crucial pour le développeur d’extensions de maîtriser les limites en termes de quotas et permissions, ainsi que la distinction entre règles statiques et dynamiques. La compréhension fine des conditions et actions, notamment en ce qui concerne les domaines, types de ressources, et actions possibles, conditionne la capacité à concevoir des extensions efficaces et respectueuses de la vie privée des utilisateurs.

Enfin, bien que l’API declarativeNetRequest offre une simplification des interactions avec les requêtes réseau, il est essentiel de garder à l’esprit que le contrôle granulaire et le comportement des règles peuvent varier selon les navigateurs et leurs politiques de sécurité. Il convient donc d’étudier les documentations officielles, notamment celle de Google Chrome, pour rester informé des évolutions et restrictions propres à chaque environnement.