【问题标题】:Rshiny: How can I call my JS authentication function such that the Rshiny app can consume the result?R Shiny:如何调用我的 JS 身份验证函数,以便 Rshiny 应用程序可以使用结果?
【发布时间】:2020-11-04 05:51:15
【问题描述】:

所以我有一个 Rshiny 应用程序设置为在服务器上发布,但我们需要一个 API 身份验证令牌来确保给定用户具有访问权限。 Authentication 过程在应用程序外部的 JS 标签中处理,而实际的 Rshiny 过程保存在页面上的 iFrame 中。

我将 js 脚本外部保存在与应用程序一起打包的 www/ 子目录中。 JS 脚本查询 localStorage 中的值以确定用户 ID,并使用此令牌 ping API 验证以确定访问权限。它看起来像这样(fetch 是一个自定义函数,它查询本地存储以设置 auth 值)。

/**
 * This Fn ! using to vaidate the user login access
 * @param none
 */
(function validateUserLoginInfo() {
    console.log("Sending user acess");
    var url = `https://authentication-url.com/isAuthy `;
    fetch(url, { method: 'GET' }, function (response) {
        if (response) {
            // user validation is Successfully done
            // $("#userValidated").val("Yes");
        } else {
            //invalid user access/login failure
            //Shiny.setInputValue("userValidated","No")
            // $("#userValidated").val("No");
        }
    });
})(); // => self executing Fn !

我实际上想要做的是运行这个 JS 函数,以便成功产生一个传递到 Rshiny 服务器环境的输入,例如input$isUserValidated,因此我可以路由应用程序进程并提醒实例用户无权访问。我进行了设置,以便“欢迎”页面文本根据此验证响应而更改,并且随后会从实例中隐藏带有分析的实际选项卡。

在 JS 函数中的 if (response) else 调用中,注释掉的行是我尝试将响应传递给服务器环境的尝试,但这些都没有奏效。而且我相信我从应用程序调用这个函数的方式是有效的,但我不确定函数 validateUserLoginInfo 是否真的有效。

所以我真的可以把我的困惑分解成两个步骤

  1. 通过tags$head(tags$script(type="text/javascript", src = "www/authenticateUser.js"))includeScript('www/authenticateUser.js') 获取脚本后,如何从r 服务器运行实际的validateUserLoginInfo() 函数?还是它已经在应用加载时自动运行?

  2. 在调用 validateUserLoginInfo() 时,如何传递来自该调用的响应,以便 R 服务器可以使用它?

这是一个简单的应用程序,可以捕获我正在寻找的内容。 “authenticateUser.js”函数可以被认为是一个返回简单“是”或“否”的函数,我只是试图从 R 服务器访问该答案。

ui <- fluidPage(
  includeScript('www/authenticateUser.js')
  textOutput('authed'),
)
server <- function(input,output,session){
  output$authed <- renderText({
    # No clue which one of these works; none have worked for me so far
    response <- input$userValidated
    response2 <- validateUserLoginInfo()
    response3 <- shinyjs::js$validateUserLoginInfo()
    return(c(response,response2,response3))
  })
}

我已经四处寻找答案,但似乎找不到任何能满足我在这里需要完成的任务。从 JS Shiny 发送警报或 onClick 事件似乎是大多数人将 JS 用于 w.r.t 的方式。瑞希尼。因此,我们将不胜感激任何和所有帮助。谢谢。

【问题讨论】:

    标签: javascript r shiny


    【解决方案1】:

    在 Shiny 服务器中,尝试将 renderText 的输出包装在 observeEvent 中,当 userValidated 的值发生变化时运行。

    server <- function(input, output, session) {
      observeEvent(input$userValidated, {
        output$auth <- renderText({
           input$userValidated
        })
      }, ignoreNULL = TRUE)
    }
    

    在js函数validateuserLoginInfo中,使用response.ok判断请求状态,并相应设置userValidated的值。

    我不确定您需要随请求发送哪些信息,因此这里有一个示例来演示这些概念。在示例中,我编写了一个简短的请求,用于评估 RStudioRStudi 是否是有效的 GitHub 用户(在请求中使用第二个 url 时会失败)。

    library(shiny)
    
    # js
    js <- '
    // validate user (this will run on page load)
    (function validateUserLoginInfo() {
        console.log("Sending user acess");
    
        // set url (using github API as a generic example; test each url)
        //var url = "https://api.github.com/users/rstudio" // this will pass
        var url = "https://api.github.com/users/rstudi" // this will fail
    
        // create a new request
        fetch(url, {method: "GET"})
        .then((response) => {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error(response.status);
            }
        })
        .then((result) => {
    
            // set shiny input as true
            Shiny.setInputValue("userValidated", JSON.stringify(true));
    
        }).catch((error) => {
    
            // set input as false + log error
            Shiny.setInputValue("userValidated", JSON.stringify(false));
            console.log(error);
        });
    
    })();
    '
    
    # ui
    ui <- fluidPage(
      textOutput("authed"),
      tags$script(HTML(js))
    )
    
    # server
    server <- function(input, output, session) {
    
        # run when change
        observeEvent(input$userValidated, {
            response <- jsonlite::fromJSON(input$userValidated)
            output$authed <- renderPrint({
                response
            })
        }, ignoreNULL = TRUE)
    }
    
    # app
    shinyApp(ui, server)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-16
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      • 2017-02-14
      相关资源
      最近更新 更多