89 votes

Comment le navigateur sait-il quand il doit inviter l'utilisateur à enregistrer son mot de passe ?

Ceci est lié à la question que j'ai posée ici : Comment faire pour que le navigateur demande d'enregistrer le mot de passe ?

Voici le problème : je n'arrive pas à faire en sorte que mon navigateur me demande d'enregistrer le mot de passe du site que je suis en train de développer. (Je parle de la barre qui apparaît parfois lorsque vous soumettez un formulaire sur Firefox, qui dit "Se souvenir du mot de passe pour votre site.com ? Oui / Pas maintenant / Jamais")

C'est très frustrant car cette fonctionnalité de Firefox (et de la plupart des autres navigateurs modernes, qui, je l'espère, fonctionnent de manière similaire) semble être un mystère. C'est comme un tour de magie que le navigateur fait, où il regarde votre code, ou ce que vous soumettez, ou quelque chose, et si cela "ressemble" à un formulaire de connexion avec un champ pour le nom d'utilisateur (ou l'adresse e-mail) et un champ pour le mot de passe, il propose d'enregistrer.

Sauf dans ce cas, où il ne propose pas cette option à mes utilisateurs après qu'ils aient utilisé mon formulaire de connexion, et cela me rend fou :-)

(J'ai vérifié les paramètres de mon Firefox - je n'ai PAS dit au navigateur "jamais" pour ce site. Il devrait me le demander).

Ma question

Quelle est l'heuristique utilisée par Firefox pour savoir quand il doit inviter l'utilisateur à enregistrer ? Il ne devrait pas être trop difficile de répondre à cette question, puisqu'elle se trouve dans les sources de Mozilla (je ne sais pas où chercher, sinon j'essaierais de le faire moi-même). Je n'ai pas non plus eu de chance de trouver un billet de blog ou une autre note similaire des développeurs de Mozilla à ce sujet.

(La réponse à cette question pour Safari ou IE ne me dérangerait pas ; j'imagine que tous les navigateurs utilisent des règles très similaires, donc si j'arrive à la faire fonctionner dans l'un d'eux, elle fonctionnera dans les autres).

(* Notez que si votre réponse a quelque chose à voir avec les cookies, le cryptage ou toute autre chose qui concerne la façon dont je stocke les mots de passe dans ma base de données locale, il y a de fortes chances que vous ayez mal compris ma question :-)

1 votes

Je ne sais pas. Votre formulaire est-il un formulaire POST avec un champ de type mot de passe ?

2 votes

Oui, enveloppé dans des balises <form>, et les champs sont nommés 'nom d'utilisateur' et 'mot de passe'. Je le charge comme une couche séparée avec AJAX, mais disqus.com le fait aussi (juste pour donner un exemple) et ça marche très bien pour eux. C'est pourquoi, plutôt que de (continuer à) modifier les choses au hasard pour voir si cela peut aider, je veux découvrir exactement comment le navigateur pense.

55voto

bta Points 22525

D'après ce que j'ai lu, je pense que Firefox détecte les mots de passe par form.elements[n].type == "password" (en parcourant tous les éléments du formulaire) et détecte ensuite le champ "nom d'utilisateur" en recherchant, en remontant dans les éléments du formulaire, le champ de texte situé immédiatement avant le champ "mot de passe" (plus d'informations). aquí ). Vous pouvez essayer quelque chose de similaire en Javascript et voir si vous pouvez détecter votre champ de mot de passe.

De ce que je peux dire, votre formulaire de connexion doit faire partie d'une <form> ou Firefox ne le détectera pas. Réglage de id="password" sur votre champ de mot de passe ne peut probablement pas faire de mal non plus.

Si cela vous pose encore de nombreux problèmes, je vous recommande de poser la question sur l'une des listes de diffusion des développeurs du projet Mozilla (vous pourriez même obtenir une réponse du développeur qui a conçu la fonctionnalité).

2 votes

C'est merveilleux. Merci. C'est ce que je cherche.

1 votes

Cela m'a permis de le faire fonctionner dans Firefox, mais je n'ai pas de chance avec Chrome. Voici le formulaire que j'utilise : <form id="myForm" action="#"> <input id="username"> <input id="password" type="password"> </form>

3 votes

@1.21gigawatts- Il n'y a pas de manière "standard" de faire cela (à ma connaissance), donc différents navigateurs peuvent le faire légèrement différemment. Je ne sais pas en quoi le processus de Chrome diffère de celui de Firefox, mais vous pourrez peut-être le découvrir en consultant le code source de Chrome. La seule façon de savoir comment Firefox procède est de lire son code. C'est le genre de chose que quelqu'un doit documenter dans un grand tableau, en indiquant comment chaque navigateur procède...

18voto

user324356 Points 111

J'ai eu le même problème et j'ai trouvé une solution :

  1. pour que le navigateur demande à stocker le mot de passe, les cases du nom d'utilisateur et du mot de passe doivent se trouver dans un formulaire et ce formulaire doit être effectivement soumis. Le bouton d'envoi pourrait renvoyer false à partir du gestionnaire onclick (de sorte que l'envoi ne se produise pas réellement).

  2. pour que le navigateur puisse restaurer le mot de passe précédemment enregistré, les zones de saisie doivent exister dans le formulaire HTML principal et ne pas être créées dynamiquement par le biais de javascript. Le formulaire peut être créé avec display:none.

Il est nécessaire de noter que le mot de passe est rempli dès que la page est chargée et qu'il est présent pendant toute la session, il peut donc être lu par un javascript injecté : cela rend de telles attaques bien plus graves. Pour éviter cela, il est raisonnable de renvoyer vers une page séparée uniquement pour se connecter, et cela résout tous les problèmes pour lesquels vous avez commencé à lire ce sujet :). Comme solution partielle, j'efface les champs lors de la soumission du formulaire - si l'utilisateur se déconnecte et veut se reconnecter, le mot de passe n'est pas rempli par le navigateur, mais c'est mineur pour moi.

Viliam


0 votes

Fonctionne dans Firefox 3.5 et IE8, ne fonctionne pas dans Chrome (le point 1 ne fonctionne pas). Peut-être que le submit doit être réel...

0 votes

User324356 - J'ai mis le formulaire à "#" puis j'ai appelé myForm.submit() et cela a fonctionné dans Firefox mais pas dans Chrome.

1 votes

Fyi : Lorsque vous utilisez return false o event.preventDefault() cela ne fonctionnera pas dans Chrome à cause de ce bogue : code.google.com/p/chromium/issues/detail?id=282488

10voto

Nick Bastin Points 12627

Vous devriez regarder le Débogage du gestionnaire de mots de passe Mozilla et la page docs nsILoginManager pour les auteurs d'extensions (juste pour les détails techniques de la façon dont Firefox traite la gestion des mots de passe). Vous pouvez creuser dans les réponses de cette page et d'autres pages liées à celle-ci pour découvrir plus que vous n'avez probablement jamais voulu savoir comment le gestionnaire de mots de passe interagit avec les sites et les extensions.

(Plus précisément, comme indiqué dans la documentation sur le débogage du gestionnaire de mots de passe, assurez-vous que l'autocomplétion n'est pas désactivée dans votre code html, car cela supprimera l'invitation à enregistrer le nom d'utilisateur et le mot de passe).

7voto

1.21 gigawatts Points 2457

Cela semble fonctionner pour Firefox, Chrome et Safari sur Mac. Non testé sur Windows.

<form id="bridgeForm" action="#" target="loginframe" autocomplete="on">
    <input type="text" name="username" id="username" />
    <input type="password" name="password" id="password"/>
</form>

<iframe id="loginframe" name="loginframe" src="anyblankpage.html"></iframe>

Il faut l'ajouter à la page. Il ne peut pas être ajouté dynamiquement. Le formulaire et la iframe peuvent être configurés en display:none. Si vous ne définissez pas le src de la iframe, l'invite ne s'affichera pas avant que vous ayez soumis le formulaire au moins une fois.

Puis appelez le formulaire submit() :

bridgeForm.submit();

L'action peut être facultative et l'autocomplétion peut être facultative. Je n'ai pas testé.

Note : Sur certains navigateurs, le formulaire doit être exécuté sur un serveur (pas sur l'hôte local ni sur le système de fichiers) avant que le navigateur ne réponde.

Alors ça :

http://www.mysite.com/myPage.html

pas ça :

http://126.0.0.1/myPage.html
http://localhost/myPage.html
file://directory/myPage.html

0 votes

@ErikAronesty avez-vous trouvé une solution ? J'ai remarqué que dans certains navigateurs (safari) la page doit être sur un serveur et non sur l'hôte local ou le système de fichiers.

1 votes

Chrome 46 a corrigé son mauvais comportement - non iframe Les solutions de contournement ne sont plus nécessaires. Voir stackoverflow.com/a/33113374/810109

6voto

110maor Points 11

Cela fonctionne pour moi avec angular, chrome, firefox : (J'ai cherché et testé pendant des heures - pour chrome le paramètre d'action du formulaire ( # ) était la réponse. @1.21 gigawatts Merci ! !! Votre réponse était inestimable).

formulaire

firefox 30.0 - n'a pas besoin d'une iframe cachée et d'un bouton de soumission (comme indiqué ci-dessous), mais a besoin de la directive "login-form-autofill-fix" pour reconnaître les justificatifs remplis automatiquement, comme suit :

<form name="loginForm" login-form-autofill-fix action="#" target="emptyPageForLogin" method="post" ng-submit="login({loginName:grpEmail,password:grpPassword})">
<input type="text" name=username" id="username" ng-model="grpEmail"/>
<input type="password" name="password" id="password" ng-model="grpPassword"/>
<button type="submit">Login</button>
</form>

iframe cachée

chrome 35.0 - n'a pas besoin de la directive ci-dessus, mais a besoin d'un iframe caché et d'un bouton d'envoi sur le vrai formulaire. La iframe cachée ressemble à

<iframe src="emptyPageForLogin.html" id="emptyPageForLogin" name="emptyPageForLogin" style="display:none"></iframe>

directive angulaire (utilisant jqLite)

Cela fonctionne avec angular 1.2.18

module.directive('loginFormAutofillFix', function() { 
            return function(scope, elem, attrs) {
        if(!attrs.ngSubmit) {
            return;
        }
        setTimeout(function() {
            elem.unbind("submit").bind("submit", function(e) {
                //DO NOT PREVENT!  e.preventDefault(); 
                elem.find("input").triggerHandler("input");
                scope.$apply(attrs.ngSubmit);
            });
        }, 0);
});

amendement

  • après quelques tests, je me suis rendu compte que chrome a besoin d'un petit délai d'attente pour la méthode de connexion angulaire (200ms) - il semble que la redirection soit parfois trop rapide pour le gestionnaire de mot de passe.
  • il vaut mieux vider le cache du navigateur... à chaque changement

0 votes

Depuis la dernière version de chrome, le pw-manager ne remplit le formulaire que parfois. aussi le pw-manager s'affiche parfois, parfois non... cela semble être une fonction aléatoire maintenant.

0 votes

Le nouveau firefox ignore le champ de mot de passe auto-rempli. le triggerHandler("input") ne fonctionne pas. cela peut être résolu avec un événement natif (document.createEvent) - le dispatcher et le déclencher.

1 votes

Chrome 46 a corrigé son mauvais comportement - non iframe Les solutions de contournement ne sont plus nécessaires. Voir stackoverflow.com/a/33113374/810109

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X