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

时间:2019-11-15 18:06:17

标签: r shiny google-oauth google-sheets-api google-authentication

我正在尝试创建一个闪亮的应用程序,该应用程序首先使用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>")
      })
  }
)

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);
}

如何访问id_token并将其传递给sheets_auth函数?

2 个答案:

答案 0 :(得分:3)

在浏览器控制台中执行以下命令,以验证其是否返回实际令牌。

  console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse()));

{ "token_type":"Bearer", "login_hint":"<Huge mess of letters>", "expires_in":2112, "id_token":"<insert your ridiculously long string here>",...}

另一个日志,使用true标志进行验证:

console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(true)));

    { "token_type":"Bearer", "access_token":"<an actual access token goes here>", "scope":"<whatever scopes you have authorized>", "login_hint":"<another mess of letters>", "expires_in":2112, "id_token":"<Insert your ridiculously long string here>", ...}

仔细检查:有时,如果我们不发送范围,则令牌ID可能不存在,您可以通过

进行修复
gapi.auth2.init({
  client_id: <googleClientID>,
  'scope': 'https://www.googleapis.com/auth/plus.login'
})

来源:GoogleUser.getAuthResponse() doesn't contain access_token

答案 1 :(得分:1)

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

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

也就是说,如果您想要来处理令牌,我会制作一个精简版的应用程序,以捕获令牌供以后使用(我对{{1}经验不足}来修改应用程序的该部分,因此我将其切成一个最低限度的应用程序)。

下面的版本对我来说“有效”,但是可能是由于削减了JavaScript的缘故,我不得不在控制台中回答一些shinyjs问题以完成授权过程(这显然是不希望的) UI设计)。

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

googlesheets4