I have been trying for the last few days to solve this, and having followed many of the examples and documentation out there without joy, I would like some assistance.
The following gives the Google authorization page, but then fails on returning to the handleOAuth2Callback page with the following error:
ERROR: Post https://accounts.google.com/o/oauth2/token: not an App Engine context
What am I doing wrong?
import (
"google.golang.org/appengine"
"google.golang.org/appengine/log"
"google.golang.org/cloud"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
// "google.golang.org/api/drive/v2"
"html/template"
"net/http"
)
var cached_templates = template.Must(template.ParseGlob("templates/*.html"))
var conf = &oauth2.Config{
ClientID: "my client id",
ClientSecret: "my client secret",
RedirectURL: "http://localhost:10080/oauth2callback",
Scopes: []string{
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/userinfo.profile",
},
Endpoint: google.Endpoint,
}
func init() {
http.HandleFunc("/", handleRoot)
http.HandleFunc("/authorize", handleAuthorize)
http.HandleFunc("/oauth2callback", handleOAuth2Callback)
}
func handleRoot(w http.ResponseWriter, r *http.Request) {
err := cached_templates.ExecuteTemplate(w, "notAuthenticated.html", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
}
}
func handleAuthorize(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
url := conf.AuthCodeURL("")
http.Redirect(w, r, url, http.StatusFound)
}
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
hc := &http.Client{}
ctx := cloud.NewContext(appengine.AppID(c), hc)
log.Infof(c, "Ctx: %v", ctx)
code := r.FormValue("code")
log.Infof(c, "Code: %v", code)
// Exchange the received code for a token
tok, err := conf.Exchange(ctx, code)
// tok, err := conf.Exchange(oauth2.NoContext, code)
if err != nil {
log.Errorf(c, "%v", err)
}
log.Infof(c, "Token: %v", tok)
client := conf.Client(oauth2.NoContext, tok)
log.Infof(c, "Client: %v", client)
}
My current solution, including logging the logged in users display name and all the files in their Google Drive - please comment if you see any errors or improvements: