R Shiny: uwierzytelnianie użytkownika dla jednej aplikacji R.


Tworzę aplikację R Shiny i chcę dodać nazwę użytkownika i dane logowania. Sprawdziłem demo RStudio, ale jest to tylko z ShinyServer Pro i używam pakietu mongolite do tworzenia kopii zapasowych formData w Mongodb.
Czy istnieje sposób, aby wymusić dodawanie danych logowania użytkowników przed wygenerowaniem aplikacji interfejsu użytkownika?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

ShinyProxy
https://www.shinyproxy.io/, serwer Shiny typu open source oparty na Docker i Spring Java, został opracowany w celu rozwiązania tego problemu. Umożliwia wprowadzenie użytkowników do pliku konfiguracyjnego aplikacji, połączenie z serwerem LDAP, użycie SSO/Keycloak lub zalogowanie się do sieci społecznościowej.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto przykład wykorzystania plików cookie do uwierzytelniania. Więcej informacji można znaleźć na moim blogu

tutaj
https://calligross.de/post/usi ... hiny/
.
Najpierw prześlij plik cookie js na www/folder:
if (!dir.exists('www/')) {
dir.create('www')
}download.file( url = 'https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js',
destfile = 'www/js.cookies.js')

Zainstaluj wymagane pakiety:
install.packages(c('shiny', 'shinyjs', 'bcrypt'))

Zapisz następujący kod jako app.R i kliknij przycisk Uruchom aplikację:
library(shiny)
library(shinyjs)
library(bcrypt)
# This would usually come from your user database.# Never store passwords as clear text
password_hash <- hashpw('secret123') # Our not so random sessionid
# sessionid <- paste(# collapse = '',
# sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE)
# )
sessionid <- "OQGYIrpOvV3KnOpBSPgOhqGxz2dE5A9IpKhP6Dy2kd7xIQhLjwYzskn9mIhRAVHo"
jsCode <- '
shinyjs.getcookie = function(params) {
var cookie = Cookies.get("id");
if (typeof cookie !== "undefined") {
Shiny.onInputChange("jscookie", cookie);
} else {
var cookie = "";
Shiny.onInputChange("jscookie", cookie);
}
}
shinyjs.setcookie = function(params) {
Cookies.set("id", escape(params), { expires: 0.5 });
Shiny.onInputChange("jscookie", params);
}
shinyjs.rmcookie = function(params) {
Cookies.remove("id");
Shiny.onInputChange("jscookie", "");
}
'server <- function(input, output) { status <- reactiveVal(value = NULL)
# check if a cookie is present and matching our super random sessionid
observe({
js$getcookie()
if (!is.null(input$jscookie) &&
input$jscookie == sessionid) {
status(paste0('in with sessionid ', input$jscookie))
}
else {
status('out')
}
}) observeEvent(input$login, {
if (input$username == 'admin' &
checkpw(input$password, hash = password_hash)) {
# generate a sessionid and store it in your database,
# sessionid <- paste( # collapse = '',
# sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE)
# )
# but we keep it simple in this example...
js$setcookie(sessionid)
} else {
status('out, cause you don\'t know the password secret123 for user admin.')
}
}) observeEvent(input$logout, {
status('out')
js$rmcookie()
}) output$output <- renderText({
paste0('You are logged ', status())}
)
}ui <- fluidPage( tags$head( tags$script(src = "js.cookies.js")
),
useShinyjs(),
extendShinyjs(text = jsCode),
sidebarLayout( sidebarPanel( textInput('username', 'User', placeholder = 'admin'),
passwordInput('password', 'Password', placeholder = 'secret123'),
actionButton('login', 'Login'),
actionButton('logout', 'Logout')
),
mainPanel( verbatimTextOutput('output')
)
))shinyApp(ui = ui, server = server)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Cóż, możesz to zrobić z kodu za pomocą
renderUI
i zmieniając interfejs użytkownika w locie. Oto przykład, jak to zrobić:
library(shiny)
library(ggplot2)u <- shinyUI(fluidPage( titlePanel("Shiny Password"), sidebarLayout(position = "left",
sidebarPanel( h3("sidebar panel"),
uiOutput("in.pss"),
uiOutput("in.clr"),
uiOutput("in.titl"),
uiOutput("in.cnt"),
uiOutput("in.seed") ),
mainPanel(h3("main panel"),
textOutput('echo'),
plotOutput('stdplot')
)
)))pok <- Fs <- shinyServer(function(input, output)
{
output$in.pss <- renderUI({ input$pss; if (pok) return(NULL) else return(textInput("pss","Password:","")) })
output$in.clr <- renderUI({ input$pss; if (pok) return(selectInput("clr","Color:",c("red","blue"))) else return(NULL) })
output$in.titl <- renderUI({ input$pss; if (pok) return(textInput("titl","Title:","Data")) else return(NULL) })
output$in.cnt <- renderUI({ input$pss; if (pok) return(sliderInput("cnt","Count:",100,1000,500,5)) else return(NULL) })
output$in.seed <- renderUI({ input$pss; if (pok) return(numericInput("seed","Seed:",1234,1,10000,1)) else return(NULL) })
histdata <- reactive( {
input$pss;
validate(need(input$cnt,"Need count"),need(input$seed,"Need seed"))
set.seed(input$seed)
df <- data.frame(x=rnorm(input$cnt))
}
)
observe({
if (!pok) {
password <- input$pss
if (!is.null(password) && password == "pass") {
pok <<- TRUE
}
}
}
)
output$echo = renderText( {
if (pok) {
s <- sprintf("the %s is %s and has %d rows and uses the %d seed",
input$ent,input$clr,nrow(histdata()),input$seed)
} else {
s <- ""
}
return(s)
}
)
output$stdplot = renderPlot( {
input$pss
if (pok) {
return(qplot(data = histdata(),x,fill = I(input$clr),binwidth = 0.2,main=input$titl))
} else {
return(NULL)
}
}
)
})
shinyApp(ui=u,server=s)


Rentowność
>
to przy logowaniu:
https://i.stack.imgur.com/BUqXR.png
I to po wpisaniu zakodowanego na stałe hasła „pass”.
https://i.stack.imgur.com/HuYu0.png
Jasne, programowanie w ten sposób jest trochę niezręczne, ale możesz użyć zakładek i je ukryć, być może używając podobnej logiki.
Lub, jeśli używasz shinyServer, prawdopodobnie możesz umieścić filtr przed witryną. Ale oto jak podszedłbym do tego w Lśniącym roku.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz dodać uwierzytelniający serwer proxy przed aplikacją Shiny w następujący sposób:

https://www.datascienceriot.co ... ginx/ Chris
https://www.datascienceriot.co ... kris/
/
To jest szkieletowa konfiguracja Nginx, która przekierowuje z portu HTTPS 443 do serwera Shiny działającego na porcie 8000.
server {
listen 443;
server_name shinyservername; ssl on;
ssl_certificate ...
ssl_certificate_key ...
ssl_dhparam ... location/{
proxy_pass [url=http://yourdestinationIP:8000;]http://yourdestinationIP:8000;[/url]
proxy_set_header X-Forwarded-Proto $scheme;
add_header Front-End-Https on;
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
auth_basic "Restricted";
auth_basic_user_file/etc/nginx/htpasswd;
}
}

Ustaw zaporę sieciową swojego hosta na otwarcie portu 443 i zezwalaj tylko na połączenia hosta lokalnego z serwerem Shiny na porcie 8000:
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -s localhost --dport 8000 -j ACCEPT
iptables -A INPUT -p tcp --dport 8000 -j DROP

Dodaj statyczne dane logowania dla co najmniej jednego użytkownika do
/ etc/nginx/htpasswd
:
htpasswd –c/etc/nginx/htpasswd myshinyuser

Jedną z wad (z wielu) jest to, że uwierzytelnia to & amp; autoryzuj, ale nie przekaże informacji o uwierzytelnionym użytkowniku do Twojej aplikacji. Aby to zrobić, potrzebujesz integracji uwierzytelniania Shiny Server Pro, która przekazuje użytkownika w sesji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Niedawno napisałem pakiet R, który zawiera moduły we/wy, które można zintegrować z dowolnym frameworkiem interfejsu użytkownika ładowania początkowego.
Przykładowy post na blogu Shinydashboard
https://paul.rbind.io/2018/11/ ... uthr/
Pakiet REPO
https://github.com/PaulC91/shinyauthr
katalog
inst/
w repozytorium pakietów zawiera kod przykładowej aplikacji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używam shinyAppLogin zamiast shinApp:
# R code
shinyAppLogin <- function( ui, server, title="Restricted Area", accounts = list(admin="admin"), ...) {
ui_with_login <- bootstrapPage(theme = "login_style.css",
div(class="login-page",
div(class="form",
h1(title), br(),
tags$form(class="login-form",
textInput(inputId = "user", label = NULL, placeholder="Username"),
passwordInput(inputId = "pass", label = "", placeholder = "Password" ),
actionButton(inputId = "login", label = "Login")
) ) ) ) server_with_login <- function(input, output, session) { observeEvent(input$login, ignoreNULL = T, { if ( input$user %in% names(accounts) && input$pass == accounts[[input$user]] ) { removeUI(selector = "body", multiple = T, immediate = T, session = session)
insertUI(selector = "html", where = "beforeEnd", ui = ui, immediate = T, session = session )
server(session$input, session$output, session = session)
}
} ) } shinyApp(ui = ui_with_login, server = server_with_login, ...)
}

wtedy mój kod wyglądałby tak:
shinyAppLogin (my_ui, nodemy_server)
Ekran logowania ze stylami
https://i.stack.imgur.com/4aU9V.png
następnie użyłem CSS z

wprowadź tutaj opisy linków
https://bootsnipp.com/snippets ... -form
po prostu zapisz swój css na www/login_style.css
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Pakiet
polished
R dodaje uwierzytelnianie i zarządzanie użytkownikami do każdej aplikacji Shiny:

https://github.com/Tychobra/polished
https://github.com/Tychobra/polished
Oto zrzut ekranu domyślnej strony logowania, którą otrzymujesz po polerowaniu:
https://i.stack.imgur.com/ZZoZ9.pngMożesz łatwo zastąpić dopracowane logo i kolory własnym brandingiem na stronach logowania i rejestracji.

Polished zawiera również pulpit nawigacyjny do zarządzania użytkownikami aplikacji:
https://i.stack.imgur.com/eFjyx.pngMożesz użyć powyższego pulpitu nawigacyjnego, aby dodawać/edytować/usuwać użytkowników z aplikacji Shiny.
Baza danych PostgreSQL jest wymagana do zarządzania użytkownikami
dopracowanymi
. Możesz bezpłatnie skonfigurować dopracowaną bazę danych PostgreSQL, postępując zgodnie z instrukcjami w pliku README powyższego połączonego repozytorium pakietów.
Alternatywnie, jeśli chcesz uniknąć konfigurowania i zarządzania bazą danych PostgreSQL, możesz skonfigurować polished za pomocą polished.tech, co wymaga mniej początkowej konfiguracji i konserwacji:

https://polished.tech
https://polished.tech/
/

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się