Utilisation de nsILoginManager
Un article de MDC.
Cet article traite de fonctionnalités introduites dans Firefox 3
[modifier] Travail avec le gestionnaire d'identification
Les extensions ont souvent besoin de conserver de manière sûre des mots de passe vers des sites et applications Web. Pour ce faire, elles peuvent utiliser nsILoginManager, qui permet le stockage sécurisé de mots de passe sensibles, et nsILoginInfo, qui permet de garder des informations d'identification.
[modifier] Obtention de nsILoginManager
Pour obtenir un composant implémentant nsILoginManager, utilisez le code suivant :
var passwordManager = Components.classes["@mozilla.org/login-manager;1"]
.getService(Components.interfaces.nsILoginManager);
La plupart des fonctions du gestionnaire d'identification prennent un objet nsILoginInfo comme paramètre. Celui-ci contient les attributs suivants : nom d'hôte, URL de soumission de formulaire, domaine d'identification HTTP, nom d'utilisateur, champ de nom d'utilisateur, mot de passe et champ de mot de passe. Seuls les attributs de nom d'hôte, nom d'utilisateur et mot de passe sont obligatoires, tandis que les autres champs sont définis selon que l'identification correspond à un formulaire de page Web ou pour une identification sur un site HTTP/FTP. Consultez les définitions d'attributs de nsILoginInfo pour plus de détails. La définition d'un objet nsILoginInfo est simple :
var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
Components.interfaces.nsILoginInfo,
"init");
var loginInfo = new nsLoginInfo(hostname, formSubmitURL, httprealm, username, password,
usernameField, passwordField);
[modifier] Exemples
[modifier] Création d'un login pour une page Web
var formLoginInfo = new nsLoginInfo('http://www.example.com',
'http://login.example.com', null,
'joe', 'SeCrEt123', 'uname', 'pword');
Ce login correspondrait à un formulaire HTML comme :
<form action="http://login.example.com/foo/authenticate.cgi"> Veuillez vous identifier. Nom d'utilisateur : <input type="text" name="uname"> Mot de passe : <input type="password" name="pword"> </form>
[modifier] Création d'un login d'authentification pour un site
var authLoginInfo = new nsLoginInfo('http://www.example.com',
null, 'ExampleCo Login',
'alice', 'SeCrEt321', null, null);
Ceci correspondrait à un login sur http://www.example.com où le serveur enverrait une réponse telle que :
HTTP/1.0 401 Authorization Required Server: Apache/1.3.27 WWW-Authenticate: Basic realm="ExampleCo Login"
[modifier] Création d'un login pour une extension locale
var extLoginInfo = new nsLoginInfo('chrome://firefoo',
'User Registration', null,
'bob', '123sEcReT', null, null);
Le gestionnaire d'idenfication traite ceci comme s'il s'agissait d'un login sur un site Web. Utilisez l'URL chrome:// de votre extension pour empêcher les conflits avec d'autres extensions, et une chaîne de domaine décrivant rapidement le but de l'identification.
[modifier] Conservation d'un mot de passe
Pour stocker un mot de passe dans le gestionnaire d'idenfification, il est nécessaire de créer auparavant un objet nsILoginInfo comme défini plus haut. Il suffit alors d'appeler la méthode addLogin() de nsILoginManager.
myLoginManager.addLogin(loginInfo);
NULL. L'un d'entre-eux doit être spécifié lors de l'enregistrement d'un mot de passe. Les champs hostname, username et password sont également obligatoires.[modifier] Récupération d'un mot de passe
La récupération d'un mot de passe depuis le gestionnaire d'identification est légèrement plus complexe. Afin de localiser un mot de passe, les champs hostname, formSubmitURL et httprealm doivent correspondre exactement à ceux utilisés pour l'enregistrement. La seule exception est que si l'adresse formSubmitURL est vide, le paramètre sera ignoré. Notez que les paramètres hostname et formSubmitURL ne doivent pas contenir le chemin vers l'URL complète. L'exemple ci-dessous peut servir de point de départ pour établir une correspondance entre des identifications par formulaire :
var hostname = 'http://www.example.com';
var formSubmitURL = 'http://www.example.com'; // not http://www.example.com/foo/auth.cgi
var httprealm = null;
var username = 'user';
var password;
try {
// Obtient le gestionnaire d'identification
var myLoginManager = Components.classes["@mozilla.org/login-manager;1"]
.getService(Components.interfaces.nsILoginManager);
// Recherche des utilisateurs pour les paramètres donnés
var logins = myLoginManager.findLogins({}, hostname, formSubmitURL, httprealm);
// Trouve l'utilisateur dans le tableau d'objets nsILoginInfo renvoyé
for (var i = 0; i < logins.length; i++) {
if (logins[i].username == username) {
password = logins[i].password;
break;
}
}
}
catch(ex) {
// Ceci se produira uniquement s'il n'y a pas de classe de composant nsILoginManager
}
Notez que le mot de passe principal de l'utilisateur lui sera demandé s'il en a choisi un pour sécuriser ses mots de passe.
[modifier] Suppression d'un mot de passe
Le retrait d'un mot de passe est simple :
myLoginManager.removeLogin(loginInfo);
Lors du retrait d'un mot de passe, l'objet nsILoginInfo spécifié doit correspondre exactement à ce qui a été enregistré, ou une exception sera déclenchée. L'attribut de mot de passe en fait partie. Voici un exemple de retrait de mot de passe sans savoir duquel il s'agit :
// valeurs d'exemple
var hostname = 'http://www.example.com';
var formSubmitURL = 'http://www.example.com';
var httprealm = null;
var username = 'user';
try {
// Obtient le gestionnaire d'identification
var passwordManager = Components.classes["@mozilla.org/login-manager;1"]
.getService(Components.interfaces.nsILoginManager);
// Recherche des utilisateurs pour cette extension
var logins = passwordManager.findLogins({}, hostname, formSubmitURL, httprealm);
for (var i = 0; i < logins.length; i++) {
if (logins[i].username == username) {
passwordManager.removeLogin(logins[i]);
break;
}
}
}
catch(ex) {
// Ceci se produira uniquement s'il n'y a pas de classe de composant nsILoginManager
}
[modifier] Modification des informations d'identification enregistrées
Le changement de mot de passe est assez simple. Comme il s'agit en faire de faire un appel à removeLogin() suivi d'un addLogin(), les contraintes sont les mêmes que pour chacun d'eux : c'est-à-dire que la valeur de l'ancien login (oldLogin) doit correspondre exactement à un login existant (voir plus haut), et que les attributs du nouveau login (newLogin) doivent être positionnés correctement :
myLoginManager.modifyLogin(oldLogin, newLogin);
[modifier] Débogage
L'implémentation du gestionnaire d'identification a la possibilité d'envoyer des messages de débogage dans la console d'erreurs, ce qui peut aider à comprendre ce qui se passe. Pour activer l'affichage de débogage, consultez http://wiki.mozilla.org/Firefox:Password_Manager_Debugging.
[modifier] Support d'anciennes versions de Firefox
Si vous désirez que votre extension supporte tant Firefox 3 que des versions plus anciennes, elle devra implémenter les composants nsILoginManager et nsIPasswordManager. Une méthode simple est présentée ci-dessous :
if ("@mozilla.org/passwordmanager;1" in Components.classes) {
// Le gestionnaire de mots de passe existe, on n'est donc pas dans Firefox 3 (il peut s'agir de Firefox 2, Netscape, SeaMonkey, etc).
// Code pour le gestionnaire de mots de passe
}
else if ("@mozilla.org/login-manager;1" in Components.classes) {
// Le gestionnaire d'identification existe, on est donc au moins dans Firefox 3
// Code pour le gestionnaire d'identification
}