Golang server side source code example needed for Google Sign-In for server-side apps

1,059 views
Skip to first unread message

sleut...@gmail.com

unread,
Nov 19, 2016, 4:05:28 PM11/19/16
to google-appengine-go
Sat 2016.11.19

Google Sign-In for server-side apps

See: 'Step 7: Exchange the authorization code for an access token' [1]

Please provide the missing Golang source code example for Google App Engine to complete this article.

Thank you,  Robin



Evan Jones

unread,
Nov 21, 2016, 12:59:12 PM11/21/16
to google-appengine-go, sleut...@gmail.com
You can call oauth2.Config.Exchange to do this for you.

sleut...@gmail.com

unread,
Nov 24, 2016, 10:04:00 AM11/24/16
to google-appengine-go, sleut...@gmail.com
Thr 2016.11.24

Evan, Thank you for your insight. I'm not an OAuth expert but the data swap seems suspect here.

When I use the Exchange() method to swap the 'code' response, the token returned is token [<nil>]

Interestingly, when I use the 'code' response in place of the token, I get back a '200 OK' but the data is 'userinfo.email' rather than the actual email address that is requested.

Although I don't expect a complete program solution, any help would be appreciated. Here's what I did: 

Thank you,  Robin


var (
googleOauthConfig = &oauth2.Config{
ClientID:     "43340633547-up1   -my client Id-  p20j3ceka4.apps.googleusercontent.com", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
ClientSecret: "5vnu   -my secret-  tcS9", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
Endpoint:     google.Endpoint,
}
)

// From POST 
    body := r.Body
    buf, err := ioutil.ReadAll(body)
    // Convert our []Byte buffer into a string
    code := string( buf )
// 2016/11/23 13:28:41 [L2592] code [4/8-lbcODbzxjE937rXRUAtJUF_LYpzPAKxgM9i33dD2Y]



    // https://github.com/golang/oauth2 - see notes in text for new AppEngine
    var ctx = newappengine.NewContext(r)

    token, err := googleOauthConfig.Exchange(ctx, code)
// 2016/11/23 10:41:12 [L2632] token [<nil>]


    client := &http.Client{
        Transport: &oauth2.Transport{
            Source: google.AppEngineTokenSource(ctx, "https://www.googleapis.com/auth/userinfo.email"),
            Base:   &newurlfetch.Transport{Context: ctx},
        },
    }

//Note: Intentional substitution of 'code' for 'token' as token response above is '<nil>'
    resp, err := client.Get("https://www.googleapis.com/auth/userinfo.email?access_token=" + code)
  
    defer resp.Body.Close()
    bufBytes := make([]byte, 1024)
    resp.Body.Read(bufBytes)
  
// 2016/11/23 13:09:44 [L2654] resp [&{200 OK 200 HTTP/1.1 1 1 map[X-Content-Type-Options:[nosniff] 
//   Expires:[Wed, 23 Nov 2016 19:09:47 GMT] Cache-Control:[private, max-age=0] Date:[Wed, 23 Nov 2016 19:09:47 GMT] 
//   Alt-Svc:[quic=":443"; ma=2592000; v="36,35,34"] Content-Type:[text/plain] X-Xss-Protection:[1; mode=block] 
//   Server:[GSE] X-Frame-Options:[SAMEORIGIN] Transfer-Encoding:[chunked]] 0xc0821a8560 14 [] true map[] 0xc0821c8000 <nil>}]
// 2016/11/23 13:09:44 [L2671] resp body close()
// 2016/11/23 13:09:44 [L2637] Resp body:  userinfo.email   



I note that the reference link provided was last updated two years ago, ref Jan 18, 2015

It appears OAuth2 had substantial changes after that post:
https://github.com/golang/oauth2  "In change 96e89be (March 2015) we removed the oauth2.Context2 type . . . "



Evan Jones

unread,
Nov 28, 2016, 12:07:37 PM11/28/16
to sleut...@gmail.com, google-appengine-go
In my experience: You only need to use the "authenticated" client if you want to call Google APIs (e.g. the Big Query API). In that case, use oauthConfig.Client() to create the client with the correct configuration for you. I've used this successfully on App Engine Standard and Flexible.

If you are trying to get the information about the authenticated user, I suggest that you use the tokeninfo endpoint, as documented here: https://developers.google.com/identity/protocols/OAuth2UserAgent#tokeninfo-validation

I don't know anything about this "userinfo" endpoint. Here is a complete Go example that can run on localhost, assuming you have configured the OAuth client to permit http://localhost:8080/oauth_callback and add the id/secret to the file: https://gist.github.com/evanj/e415d808dbb6c2a0bd866cd9d17ef5aa


As an example, here is output I just got:

Tokeninfo:
{
 ...
 "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me",
 "exp": "1480356139",
 "expires_in": "3599",
 "email": "evan....@triggermail.io",
 "email_verified": "true",
 "access_type": "online"
}


This was stolen from my BigQuery Tool project which uses OAuth to access BigQuery (the googlelogin package might be helpful as it tries to generate and verify the state parameter correctly, although it probably needs a bunch of work): https://github.com/evanj/bqtools

Good luck!


--
You received this message because you are subscribed to a topic in the Google Groups "google-appengine-go" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-appengine-go/X8pYFwVdAvs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-appengine-go+unsub...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

sleut...@gmail.com

unread,
Dec 11, 2016, 8:50:13 AM12/11/16
to google-appengine-go, sleut...@gmail.com
Sat 2016.12.10

Evan,
Thank you for taking the time to post your project to github. Using that source, I was able to successfully deploy a modified version at AppSpot. I originally had grandiose plans to incorporate Goth [1] to allow for several choices for OAuth, but kept getting context compile errors when attempting to use the newappengine context as suggested from the changes back in March 2015. [2]

I was never able to get a sample provider running even after attempting a cleanup of the Goth source. There seem to be subtle differences between a deployed GAE Go proj at AppSpot and what one may get running using the AppEngine server at localhost.

Thank you again,
Robin

[2] https://github.com/golang/oauth2  "In change 96e89be (March 2015)"

Evan Jones

unread,
Dec 13, 2016, 1:23:29 PM12/13/16
to Robin, google-appengine-go, sleut...@gmail.com
Awesome I'm glad it was useful! Maybe I should pull that package out as a separate github project ...

Evan


On Sat, Dec 10, 2016 at 11:07 AM, Robin <robinc...@gmail.com> wrote:
Sat 2016.12.10

Evan,
Thank you for taking the time to post your project to github. Using that source, I was able to successfully deploy a modified version at AppSpot. I originally had grandiose plans to incorporate Goth [1] to allow for several choices for OAuth, but kept getting context compile errors when attempting to use the newappengine context as suggested from the changes back in March 2015. [2]

I was never able to get a sample provider running even after attempting a cleanup of the Goth source. There seem to be subtle differences between a deployed GAE Go proj at AppSpot and what one may get running using the pseudo AppEngine server at localhost.
Reply all
Reply to author
Forward
0 new messages