не может получить информацию профиля пользователя с помощью Oauth2 на сервере, используя id_token, предоставленный клиентом

Я попытался войти в систему, используя идентификатор Google на своей веб-странице. Я зарегистрировал id_token от пользователя в консоли. Затем я скопировал это, передал на сервер и попытался получить информацию о пользователе. Но я получаю ошибку на сервере golang как

ошибка - oauth2: невозможно получить токен: 400 Ответ на неверный запрос: {"error": "invalid_grant"}

Это мой код стороны подачи.

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)

Мой код на стороне клиента выглядит следующим образом

<!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);
};

person IhtkaS    schedule 30.04.2017    source источник


Ответы (1)


Полученный вами id_token уже содержит информацию о нужном вам пользователе.

См. https://jwt.io, чтобы найти библиотеку Go для декодирования вашего токена.

person Spomky-Labs    schedule 30.04.2017
comment
Теперь я понимаю поток. header.payload.signature. Подпись зашифрована с использованием идентификатора клиента? Если да, то могу ли я расшифровать подпись секретным ключом? Я считаю, что идентификатор клиента - это открытый ключ, а секрет - это закрытый ключ. Верно ли мое предположение? - person IhtkaS; 01.05.2017
comment
JWT не зашифрован, а просто закодирован (Base64 Url Safe). Подпись может быть проверена с помощью открытых ключей эмитента. В вашем случае эмитентом является Google, а ключи доступны по адресу googleapis.com/oauth2/v3/certs. (или googleapis.com/oauth2/v1/certs для ключей в Формат PEM) - person Spomky-Labs; 03.05.2017