28 votes

Comment faire pour que le navigateur Web R / Shiny se souvienne du mot de passe?

Le problème

J'ai une brillante application qui requiert que l'utilisateur de connexion pour accéder à l'dataset sous-jacent.

Le nom d'utilisateur et mot de passe sont collectées à partir des champs de formulaire et soumis via une API RESTful sur un autre serveur pour obtenir un jeton d'accès qui est utilisé dans les futures demandes. Je n'ai pas inclus les détails dans cet exemple.

enter image description here

Je veux obtenir le navigateur web de se rappeler les détails de connexion et de connexion automatiquement, mais ne voit pas bien comment.

Ce que j'ai essayé

Lors de ma première mise en œuvre, l' <input type="text" name="username"> et <input type="password" name="password"> plus un actionButton ont été ajoutées dynamiquement à la page. Cela contraint l'utilisateur à se reconnecter à chaque fois que le brillant de l'application a été redémarré, qui a été complexe pour le développement et désagréable pour les utilisateurs.

J'ai ensuite trouvé https://gist.github.com/kostiklv/968927 qui détaille les conditions pour avoir le navigateur web de mémoriser le mot de passe et connectez-vous.

Brillant fonctionne sur une seule page, donc je ne pouvais pas avoir une page de connexion (ce qui permettrait de générer un nouveau brillant session, en rejetant la connexion!).

J'ai essayé différentes combinaisons de choses, ici est le plus proche que j'ai eu. Ce script correctement remplit un ancien mot de passe, mais l'utilisateur a toujours manuellement cliquez sur envoyer.

Exemple de code

Notez que j'ai personnalisé hack mon brillant pour activer type="password" à être traités de la même façon qu' type="text". Voir en bas de la question de l'accès à ce code

enregistrez ce code sous la forme login.R puis exécutez R et tapez source("login.R")

write("","blank.html")
require(shiny)
addResourcePath("login",tools:::file_path_as_absolute("./"))
runApp(list(
  ui=bootstrapPage(
    tags$form(action="#",target="loginframe",
      tags$input(id="username",type="text",placeholder="Username"),
      tags$input(id="password",type="password",placeholder="Password"),
      tags$input(id="loginButton",class="btn btn-primary",type="submit",value="Login")
    ),
    tags$iframe(name="loginframe",src="login/blank.html",style="display:none")
  ),
  server=function(input, output) {
    observe({message(
        "username ",input$username,"\n",
        "password ",input$password,"\n"
    )})
  })
)

L'analyse de ce qui s'est passé

Notez que la présence d'un html input submit button semble dire brillant qu'il doit mettre à jour les entrées une fois tous les présenter. Sans le bouton soumettre brillant mises à jour de ses entrées de chaque frappe de touche.

Le même est vrai pour brillant de l' submitButton.

Laisser la forme, mais de supprimer le bouton permet de sélectionner l'entrée de$username et$saisie de mot de passe pour accéder au serveur de code, mais...

Pour activer à la fois les classiques de la connexion de l'utilisateur et de connexion automatique, j'ai besoin de le bouton d'éviter la répétition des tentatives d'authentification (qui pourraient causer des problèmes) pour une partie des noms d'utilisateur et mots de passe.

Journal de ce qui s'est passé

Voici les journaux de la console de tests

Journal avec un bouton de soumission:

username 
password 
<enter username AA and password BB>
*no update*
<hit submit>
*browser requests to save password / yes*
username A
password B
<refresh page>
username 
password
* onscreen form inputs are populated *
<hit submit>
username A
password B

Journal sans bouton soumettre

Commentaire tags$input(id="loginButton",class="btn btn-primary",type="submit",value="Login") et avant la virgule

remarque vous pouvez demander à votre navigateur d'oublier localhost les mots de passe web pour l'instant.

username
password
<enter username AA and password BB>
username A
password
username AA
password
username AA
password B
password BB
<refresh browser>
* onscreen form inputs are not populated *
* browser requests to save password *
username
password
<refresh browser>
* onscreen form inputs are populated *
username
password
username AA
username BB

Brillant patch pour activer le mot de passe de la manipulation:

Installer à l'aide d' library(devtools)

install_github("shiny","alexbbrown",ref="password-field")

Ou le télécharger et l'installer manuellement:

https://github.com/alexbbrown/shiny.git (branch password-field)

Ou patch votre brillant manuellement:

index 9b63c7b..15377d8 100644
--- a/inst/www/shared/shiny.js
+++ b/inst/www/shared/shiny.js
@@ -1336,7 +1336,7 @@
   var textInputBinding = new InputBinding();
   $.extend(textInputBinding, {
     find: function(scope) {
-      return $(scope).find('input[type="text"]');
+      return $(scope).find('input[type="text"],input[type="password"]');
     },
     getId: function(el) {
       return InputBinding.prototype.getId.call(this, el) || el.name;

cf champ de Mot de passe à l'aide de R Brillant cadre

1voto

Aleksandr Blekh Points 388

Je crois que vous pouvez utiliser postForm() de RCurl package pour effectuer régulièrement HTTP soumettre le formulaire de demande (à moins d' Shiny pourrait interférer avec cette fonctionnalité, qui est basée sur l'utilisation de sous-jacents libcurl bibliothèque). Pour un exemple de code, veuillez voir la fonction srdaLogin() dans mon R module "getSourceForgeData.R": https://github.com/abnova/diss-floss/blob/master/import/getSourceForgeData.R.

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