Wednesday 12 June 2019

authentication - How do i get the web browser password store to remember R/Shiny passwords?

I have a shiny application that requires user to login to access the underlying dataset.



The username and password are collected from form fields and submitted via a RESTful API on another server to get an access token which is used in future requests. I haven't included those details in this example.



enter image description here



I want to get the web browser to remember the login details and login automatically, but can't quite see how.






In my first implementation, the and plus an actionButton were dynamically added to the page. This forced the user to re-login each time the shiny application was restarted, which was complex for development and unpleasant for users.



I then found https://gist.github.com/kostiklv/968927 which details the conditions for having the web browser remember the password and log in.



Shiny works on one page, so I couldn't have a separate login page (this would generate a new shiny session, discarding the login!).



I have tried various combinations of things, here is the closest I have got. This script correctly fills in a past password, but the user still has to manually hit submit.






Note that I have a custom hack my shiny in to enable type="password" to be treated the same as type="text". See bottom of question for access to this code



save this code as login.R then run R and type 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"
)})
})
)




Note that the presence of an html input submit button seems to tell shiny that it should only update the inputs once every submit. Without the submit button shiny updates its inputs every keystroke.




The same is true for shiny's submitButton.



Leaving the form but removing the button allows input$username and input$password to reach the server code, but...



To enable both conventional user login and automated login, I need the button to avoid repeated attempts to authenticate (which might cause problems) for partial usernames and passwords.





Here are the console logs from the tests




Log with a submit button:



username 
password

*no update*

*browser requests to save password / yes*
username A

password B

username
password
* onscreen form inputs are populated *

username A
password B



Log without a submit button



Comment out
tags$input(id="loginButton",class="btn btn-primary",type="submit",value="Login")
and the preceding comma



note you may want to tell your browser to forget localhost web passwords for now.



username
password


username A
password
username AA
password
username AA
password B
password BB

* onscreen form inputs are not populated *

* browser requests to save password *
username
password

* onscreen form inputs are populated *
username
password
username AA
username BB








Install using library(devtools)



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



Or download and install manually:



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


Or patch your shiny manually:



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 Password field using R Shiny framework

No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...