0

I tried to log in using the google id on my web page. I logged the id_token from the user in console. Then I copied that and passed to a server and tried to get user info. But I get an error in golang server as

err is oauth2: cannot fetch token: 400 Bad Request Response: { "error" : "invalid_grant" }

This is my serve side code.

func main() {
go func() {
    http.ListenAndServe(":8123", nil)
}()
http.HandleFunc("/", serveFile)
http.HandleFunc("/loginUser", loginUser)
<-quit
}
func loginUser(rw http.ResponseWriter, req *http.Request) {
id_token, _ := getIdToken(req)
conf := oauth2.Config{
    ClientID:     "HIDDEN.apps.googleusercontent.com",
    ClientSecret: "HIDDEN",
    Scopes: []string{
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/userinfo.profile",
    },
    Endpoint: google.Endpoint,
}
L.Errorln(id_token)
tok, err := conf.Exchange(oauth2.NoContext, id_token)
if err != nil {
    L.Errorln("err is", err)
}

L.Errorln("token is ", tok)
response, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + tok.AccessToken)

defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
L.Errorln(contents, err)

My client side code as follows

<!DOCTYPE html>
<html>
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="HIDDEN.apps.googleusercontent.com">
 <script src="https://apis.google.com/js/client:platform.js?" async defer>
 </script>
 <script  src="/login.js"></script>
 <link rel="stylesheet" type="text/css" href="/login.css">
 <title>Wander</title>
 </head>
 <body>
 <div id="g-login" class="g-signin2" data-onsuccess="onSignIn" data-
 theme="dark" ></div>

<a href="#" onclick="signOut();">Sign out</a>
<script>
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
  console.log('User signed out.');
});
}
</script>
</body>
</html>

login.js

    function onSignIn(googleUser) {
    // Useful data for your client-side scripts:
    var profile = googleUser.getBasicProfile();
    console.log("ID: " + profile.getId()); // Don't send this directly to your server!
    console.log('Full Name: ' + profile.getName());
    console.log('Given Name: ' + profile.getGivenName());
    console.log('Family Name: ' + profile.getFamilyName());
    console.log("Image URL: " + profile.getImageUrl());
    console.log("Email: " + profile.getEmail());

    // The ID token you need to pass to your backend:
    var id_token = googleUser.getAuthResponse().id_token;

    console.log("ID Token: " + id_token);
};
IhtkaS
  • 1,314
  • 3
  • 15
  • 31

1 Answers1

1

The id_token you received already contains the information of the user you need.

See https://jwt.io to find a Go library to decode your token.

Spomky-Labs
  • 15,473
  • 5
  • 40
  • 64
  • I understand the flow now. header.payload.signature. Is the signature encryted using the client id? If so then can I decrypt the signature using secret key? I believe that client id is public key and secret is private key. Is my assumption correct? – IhtkaS May 01 '17 at 05:11
  • The JWT is not encrypted but just encoded (Base64 Url Safe). The signature can be verified by using the public keys of the issuer. In your case the issuer is Google and the keys are available at https://www.googleapis.com/oauth2/v3/certs (or https://www.googleapis.com/oauth2/v1/certs for keys in PEM format) – Spomky-Labs May 03 '17 at 20:50