我正在尝试创建一个闪亮的应用程序,该应用程序首先使用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
功能?
您的主要问题是:“如何访问id_token
并将其传递给sheets_auth
功能?”
我很确定googlesheets4
库是为在后台处理令牌管理而设计的(例如,您不需要直接处理它)。实际上,文档(?sheets_token
)表示:“大多数用户不需要“手动”处理令牌,或者即使他们需要某种控制,他们也需要sheets_auth()
。”
就是说,如果您want处理令牌,我会制作一个精简版的应用程序,以捕获令牌供以后使用(我对shinyjs
的经验不足,无法修改令牌的这一部分应用程序,因此我将其切成一个最低限度的应用程序)。
下面的版本对我来说有效,但是可能是因为切掉了JavaScript,我不得不在控制台中回答一些googlesheets4
问题以完成授权过程。
一旦完成授权过程,至少在我看来,该应用程序将以最小的示例执行您要完成的所有任务。即,它: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.
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)