googleUser.getAuthResponse()。id_token不以闪亮方式返回id_token

jja*_*iak 7 r google-authentication google-oauth shiny google-sheets-api

我正在尝试创建一个闪亮的应用程序,该应用程序首先使用OAuth进行授权(请参阅https://developers.google.com/identity/sign-in/web/sign-in),然后获取一个令牌,并使用来访问使用googlesheets4库的Google工作表。登录过程正常进行,这意味着我可以看到我的电子邮件(以及的其他数据googleUser.getBasicProfile()。似乎没有id_token返回。)最小示例:

app.R

library(shiny)
library(shinyjs)
library(googlesheets4)

shinyApp(
  ui = fluidPage(
    useShinyjs(),  
    tags$head(tags$script(src="https://apis.google.com/js/platform.js")),
    tags$meta(name = "google-signin-scope", content = "profile email"),
    tags$meta(name = "google-signin-client_id", content = "<CLIENT_ID>.apps.googleusercontent.com"),
    includeScript("signin.js"),
    div(id = "signin", class = "g-signin2", "data-onsuccess" = "onSignIn"),
    actionButton("signout", "Sign Out", onclick="signOut();", class="btn-danger"),

    with(tags, dl(dt("Email"), dd(textOutput("g.email")),
                  dt("Token"), dd(textOutput("g.id_token"))
                  )),

    tableOutput("df")
  ),


  server = function(input, output) {

    output$g.email = renderText({ input$g.email }) # here my email is printed in the app
    output$g.id_token = renderText({ input$g.id_token}) # no id_token available?

    output$df <- renderTable({
      sheets_auth(token = input$g.id_token)
      read_sheet("<GOOGLE_SHEET_ID>")
      })
  }
)
Run Code Online (Sandbox Code Playgroud)

singin.js

function onSignIn(googleUser) {
  var profile = googleUser.getBasicProfile();
  Shiny.onInputChange("g.email", profile.getEmail());
  var id_token = googleUser.getAuthResponse().id_token;
  Shiny.onInputChange("g.id_token", id_token);
}

function signOut() {
  var auth2 = gapi.auth2.getAuthInstance();
  auth2.signOut();
  Shiny.onInputChange("g.email", null);       
  Shiny.onInputChange("g.id_token", null);
}
Run Code Online (Sandbox Code Playgroud)

如何访问id_token并将其传递给sheets_auth功能?

D. *_*ods 1

您的主要问题是:“我如何访问id_token它并将其传递给sheets_auth函数?”

我非常确定该googlesheets4库旨在在后台处理令牌管理(例如,您不需要直接处理它)。事实上,文档 ( ?sheets_token) 说:“大多数用户不需要“手动”处理令牌,或者即使他们需要一些控制,这sheets_auth()也是他们所需要的。”

也就是说,如果您处理令牌,我会为您的应用程序制作一个精简版本,以捕获令牌以供后续使用(我没有足够的经验来shinyjs修改应用程序的该部分,因此我将其删除以制作一个最低限度工作的应用程序)。

下面的版本对我来说“有效”,但也许由于删除了 JavaScript,我必须googlesheets4在控制台中回答一些问题才能完成授权过程(这对于此 UI 设计来说显然是不可取的)。

一旦授权过程完成,至少对我而言,该应用程序将执行您在最小示例中要完成的所有任务。也就是说,它:1) 显示经过身份验证的电子邮件,2) 显示 id_token,3) 读取并显示在帐户中找到的第一个电子表格。

library(shiny)
library(googlesheets4)

ui = fluidPage(
    actionButton("signin", "Sign In"),
    with(tags, dl(dt("Email: "), dd(textOutput("g.email")),
                  dt("Token: "), dd(textOutput("g.id_token"))
    )),
    tableOutput("df")
)

server = function(input, output) {
    # Listen for input$send changes (i.e. when the button is clicked)
    observe({ 
        input$signin
        sheets_auth()
        # TODO: Add error handling.
        # You don't need to capture the token in order to read a Google Sheet.
        # Just capturing it here to enable the display/renderText portions of the app.
        token = sheets_token() 
    })

    output$g.email <- renderText({
        # Here my email is printed in the app
        if(sheets_has_token()){
            token$auth_token$email   
        }
    }) 

    output$g.id_token <- renderText({
        # Here my id_token is printed in the app
        if(sheets_has_token()){
            token$auth_token$credentials$id_token   
        }
    }) 

    output$df <- renderTable({
        if(sheets_has_token()){
            my_sheets <- sheets_find()
            read_sheet(my_sheets$id[1])
        }
    })
}

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)