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.
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;