google-app-engine - Google App Engine Go 1.11 应用程序无法访问 Google 电子表格
问题描述
我正在尝试通过在Google App Engine Go 1.11 Standard Environment上运行的应用程序的 API 访问 google 电子表格。不幸的是,应用程序无法读取此电子表格。
我在Spreadsheets.Values.Get
通话时收到下一个错误:
googleapi: Error 403: Request had insufficient authentication scopes., forbidden
示例代码
// Sample app showing issue with GAE -> google spreadsheets
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"cloud.google.com/go/compute/metadata"
"golang.org/x/oauth2/google"
"google.golang.org/api/sheets/v4"
)
func main() {
http.HandleFunc("/", indexHandler)
// [START setting_port]
port := os.Getenv("PORT")
if port == "" {
port = "8080"
log.Printf("Defaulting to port %s\n", port)
}
// let's check app engine instance scopes
scopes, _ := metadata.Get("instance/service-accounts/default/scopes")
log.Printf("[DEBUG] metadata scopes: %s.\n", scopes)
log.Printf("Listening on port %s", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
// [END setting_port]
}
// indexHandler responds to requests with our greeting.
func indexHandler(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
client, _ := google.DefaultClient(ctx, "https://www.googleapis.com/auth/spreadsheets.readonly")
srv, err := sheets.New(client)
// Prints the names and majors of students in a sample spreadsheet:
// https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
spreadsheetId := "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
readRange := "Class Data!A2:E"
resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do()
if err != nil {
log.Fatalf("Unable to retrieve data from sheet: %v\n", err)
}
if len(resp.Values) == 0 {
fmt.Fprintf(w, "No data found.\n")
} else {
fmt.Fprintf(w, "Name, Major:\n")
for _, row := range resp.Values {
// Print columns A and E, which correspond to indices 0 and 4.
fmt.Fprintf(w, "%s, %s\n", row[0], row[4])
}
}
}
重现步骤:
1)部署应用程序:gcloud app deploy
2)在浏览器中打开(你会得到502):gcloud app browse
3)检查日志:gcloud app logs read
2018-12-11 21:44:56 default[20181211t134352] "GET / HTTP/1.1" 502
2018-12-11 21:44:57 default[20181211t134352] 2018/12/11 21:44:57 [DEBUG] metadata scopes: https://www.googleapis.com/auth/appengine.apis
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/cloud-platform
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/cloud_debugger
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/devstorage.full_control
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/logging.write
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/monitoring.write
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/trace.append
2018-12-11 21:44:57 default[20181211t134352] https://www.googleapis.com/auth/userinfo.email
2018-12-11 21:44:57 default[20181211t134352] .
2018-12-11 21:44:57 default[20181211t134352] 2018/12/11 21:44:57 Listening on port 8081
2018-12-11 21:44:58 default[20181211t134352] 2018/12/11 21:44:58 Unable to retrieve data from sheet: googleapi: Error 403: Request had insufficient authentication scopes., forbidden
有人可以帮助了解如何解决它吗?
解决方案
我之前也遇到过 App Engine 到 G Suite 集成的问题。您需要使用服务帐户密钥。默认值是不够的(我相信因为它没有私钥,但这可能是错误的)。
本质上,您需要使用您的代码上传一个密钥并使用它来获取一个Client
(而不是使用默认的):
func getOauthClient(serviceAccountKeyPath string) *http.Client {
ctx := context.Background()
data, err := ioutil.ReadFile(serviceAccountKeyPath)
if err != nil {
log.Fatal(err)
}
creds, err := google.CredentialsFromJSON(ctx, data, "https://www.googleapis.com/auth/spreadsheets.readonly")
if err != nil {
log.Fatal(err)
}
return oauth2.NewClient(ctx, creds.TokenSource)
}
推荐阅读
- php - PHP 广播日历
- java - 在 Java 中更新绑定的 JLabel 文本
- javascript - React/Redux 中的同时搜索和排序
- c - 程序崩溃,我不知道为什么
- python-3.x - 尝试获取组中的第二个最小记录时出错
- xml - 存储 XML 模式的最佳实践是什么?
- excel-formula - 带有公式的 Excel 3 色标条件格式
- javascript - .join("\n") 未使用 Vue CLI 在 JavaScript 数组中创建新行
- python - 优化慢 numpy n-body 模拟
- algorithm - 如何在至少通过某些节点一次的条件下找到最便宜的遍历路径