R Shiny: user authentication for a single app.R

前端 未结 7 1437
孤城傲影
孤城傲影 2020-12-25 14:15

I am developing a R Shiny App and want to add user name and logins. I checked the RStudio demo but that is only using the ShinyServer Pro and I am using the mongolite packag

相关标签:
7条回答
  • 2020-12-25 14:52

    ShinyProxy, an open-source Docker- and Spring Java-based Shiny server, was designed to address this issue. It allows you to hard-code users in the application configuration file, connect to an LDAP server, use SSO/Keycloak, or Social network sign-in.

    0 讨论(0)
  • 2020-12-25 14:59

    I recently wrote an R package that provides login/logout modules you can integrate with any bootstrap UI framework.

    Blogpost with example using shinydashboard

    Package repo

    the inst/ directory in the package repo contains the code for the example app.

    0 讨论(0)
  • 2020-12-25 15:05

    Well, you can do it via from code by using renderUI and changing the UI on the fly. Here is an example of how to do it:

    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 <- F
    
    s <- 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)
    

    Yields

    this at login:

    And this once you have entered the hardcoded password "pass".

    Of course programming this way is a bit awkward, but you could use tabs and hide them perhaps using a similar logic.

    Or if you are using shinyServer you could probably put a filter in front of the site. But this is how I would approach it in Shiny.

    0 讨论(0)
  • 2020-12-25 15:08

    You can add an authenticating proxy ahead of your Shiny application like this: https://www.datascienceriot.com/add-authentication-to-shiny-server-with-nginx/kris/

    This is a skeleton Nginx configuration that redirects from HTTPS port 443 to your Shiny Server running on port 8000.

    server {
        listen       443;
        server_name  shinyservername;
    
        ssl                  on;
        ssl_certificate      ...
        ssl_certificate_key  ...
        ssl_dhparam ...
    
        location / {
            proxy_pass http://yourdestinationIP:8000;
            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;
        }
    }
    

    Set your host's firewall to open port 443, and only allow localhost connections to the Shiny Server on port 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
    

    Add static credentials for one or more users into /etc/nginx/htpasswd:

    htpasswd –c /etc/nginx/htpasswd myshinyuser
    

    One downside (of many) is that this will authenticate & authorise, but it won't pass the authenticated user information to your application. For that you would need Shiny Server Pro's authentication integration which passes you the user in the session.

    0 讨论(0)
  • 2020-12-25 15:12

    I use shinyAppLogin instead of 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, ...)
    }
    

    then my code becomes: shinyAppLogin(my_ui, my_server)

    Login screen when styles

    then I used css from enter link description here just save your css in www/login_style.css

    0 讨论(0)
  • 2020-12-25 15:15

    The polished R package adds authentication and user management to any Shiny app: https://github.com/Tychobra/polished

    Here is a screenshot of the default sign in page that you get with polished:
    You can easily replace the placeholder logos and colors with your own branding on the sign in and register pages.

    Polished also comes with a dashboard to manage the users of your app:


    More detail: https://polished.tech/

    0 讨论(0)
提交回复
热议问题