GAEのエミュレータでサービスアカウントからスプレッドシートにアクセスできない
goで書いたGAE上のアプリからスプレッドシートの内容を編集したいと思い、以下のようなコードを書いたのですが、
スプレッドシートの認証で引っかかってしまいます。
どなたか気づかれたことがありましたらご教示いただけないでしょうか?
前提として、
- IAMのサービスアカウントを作成して、jsonの秘密鍵を習得しローカルにおいています。
- また、client_emailはスプレッドシートとも共有設定をしました。
- goは1.9を使っています
スプレッドシートのAPIや、
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get?hl=ja
AppEngineのチュートリアルを参考に、
https://cloud.google.com/appengine/docs/standard/go/building-app/creating-your-application
以下のようなコードを書きました。
ここでは、アクセスできればいいので、ブラウザには適当に「success」だけを出力するようにしています。
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/sheets/v4"
"google.golang.org/appengine" // Required external App Engine library
)
func httpClient(credentialFilePath string) (*http.Client, error) {
data, err := ioutil.ReadFile(credentialFilePath)
if err != nil {
return nil, err
}
conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/spreadsheets")
if err != nil {
return nil, err
}
return conf.Client(oauth2.NoContext), nil
}
func main() {
spreadsheetId := "スプレッドシートのID"
credentialFilePath := "credential.json"
client, err := httpClient(credentialFilePath)
if err != nil {
log.Fatal(err)
}
sheetService, err := sheets.New(client)
if err != nil {
log.Fatalf("Unable to retrieve Sheets Client %v", err)
}
_, err = sheetService.Spreadsheets.Get(spreadsheetId).Do()
if err != nil {
log.Fatalf("Unable to get Spreadsheets. %v", err)
}
code_str := "success" // ブラウザに表示させる文字
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
indexHandler(w, r, code_str)
})
appengine.Main() // Starts the server to receive requests
}
func indexHandler(w http.ResponseWriter, r *http.Request, code string) {
// if statement redirects all invalid URLs to the root homepage.
// Ex: if URL is http://[YOUR_PROJECT_ID].appspot.com/FOO, it will be
// redirected to http://[YOUR_PROJECT_ID].appspot.com.
if r.URL.Path != "/" {
http.Redirect(w, r, "/", http.StatusFound)
return
}
//fmt.Fprintln(w, "Hello, Gopher Network!")
fmt.Fprintln(w, code)
}
go run sample.goで実行すると「success」をブラウザから確認できました。
つまりローカルで実行すると、秘密鍵を使ってスプレッドシートにアクセスすることができています。
ところが、エミュレータを使って dev_appserver.py app.yaml を実行すると、
下記のようにoauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: not an App Engine contextと出てしまいます。
ERROR 2018-08-20 15:23:41,150 http_runtime.py:414] bad runtime process port ['']
INFO 2018-08-20 15:23:41,150 instance.py:294] Instance PID: 16732
2018/08/20 15:23:41 Unable to get Spreadsheets. Get https://sheets.googleapis.com/v4/spreadsheets/スプレッドシートのID?alt=json: oauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: not an App Engine context
なにか気づかれた点があればどなたかご教示いただけないでしょうか?
以上、よろしくお願いいたします。