Конечная точка Google oauth2 не возвращает информацию о профиле пользователя (имя и т. д.)

Я пытаюсь использовать Google oauth2 в своем веб-сервисе (golang), но не могу получить информацию о профиле пользователя (имя, фамилия).

Я пробую разные конечные точки, но каждый раз получаю такой ответ:

{
    "id":"*************",
    "email":"***@gmail.com",
    "verified_email":true,
    "picture":"https://***/photo.jpg"
}

В то же время игровая площадка Google с этим набором областей возвращает такой ответ:

{
  "family_name": "***", 
  "name": "****", 
  "picture": "https://*******/photo.jpg", 
  "locale": "ru", 
  "email": "****@gmail.com", 
  "given_name": "*****", 
  "id": "************", 
  "verified_email": true
}

Как я могу получить тот же ответ в своем веб-приложении? Люди на этом сайте и в инете советуют добавить область профиля, но я это уже сделал.

Вот мой код (сокращенный)

"golang.org/x/oauth2"
"golang.org/x/oauth2/google"

func init() {
    googleOauthConfig = &oauth2.Config{
        RedirectURL:  "*******",
        ClientID:     "*********",
        ClientSecret: "******",
        Scopes: []string{
            "https://www.googleapis.com/auth/userinfo.email",
            "https://www.googleapis.com/auth/userinfo.profile",
            "openid"},
        Endpoint: google.Endpoint,
    }
}

var googleOauthConfig *oauth2.Config

//const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v1/userinfo"
const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v2/userinfo"
//const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v3/userinfo"
const oauthGoogleURLAPI2 = "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses"
//const oauthGoogleURLAPI = "https://openidconnect.googleapis.com/v1/userinfo"

func HandleGoogleCallback(w http.ResponseWriter, r *http.Request) {
    ...

    oauthState, _ := r.Cookie(oauthstateCookieName)

    code := r.FormValue("code") 

    gtoken, err := googleOauthConfig.Exchange(oauth2.NoContext, code)

    bearer := "Bearer " + gtoken.AccessToken

    req, err := http.NewRequest("GET", oauthGoogleURLAPI, nil)
    req.Header.Add("Authorization", bearer)

    gresponse, err := http.DefaultClient.Do(req)

    contents, err := ioutil.ReadAll(gresponse.Body)

    authContent := &AuthContent{}

    err = json.Unmarshal(contents, authContent)

    log.Println(authContent)

    ...
}

Я тоже читал эту статью API-интерфейс Google Oauth2 userinfo не возвращает данные имени пользователя Но результат тот же: нет информации о профиле.

Спасибо.

Обновлять: По совету комментария немного подправил код "golang.org/x/oauth2" и получил id_token. Когда я проверил этот токен id на jwt.io, я увидел все нужные мне данные. Но я думал, что информация о профиле должна быть получена через запрос API, подобный этому

req, err := http.NewRequest("GET", <endPoint>, nil)
gresponse, err := http.DefaultClient.Do(req)

В этом примере используется только стандартная библиотека go, а gresponse содержит полный http-ответ, не так ли? Почему в ответе нет нужных мне полей?

попробуйте взять токен id и поместить его в jwt.io. Gtoken также должен содержать токен id. Мне интересно, если ваша библиотека просто неправильно анализирует ответ.

DaImTo 11.06.2019 10:00

Итак, похоже, вы правы. Когда я извлек из недр библиотеки id_token и проверил его через jwt.io, я увидел все нужные мне данные. Но я не понимаю, что не так. Я думал, что информация о профиле должна быть получена через запрос API, например req, err := http.NewRequest("GET", <endPoint>, nil) gresponse, err := http.DefaultClient.Do(req). В этом примере используется только стандартная библиотека go, а gresponse содержит полный http-ответ, не так ли? Почему в ответе нет нужных мне полей?

Sergey 11.06.2019 12:29
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
2
945
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

  1. Обработать ошибку в googleOauthConfig.Exchange(oauth2.NoContext, code)
  2. Обработать ошибку в http.DefaultClient.Do
  3. Обработать ошибку в ioutil.ReadAll(gresponse.Body)
  4. Обработать ошибку в json.Unmarshal

И вы можете найти ответ.

Также я помню, что всегда отправлял access_token в качестве параметра запроса:

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

Спасибо за Ваш ответ. В исходном коде (не сокращенном) я проверяю все возвращаемые ошибки вот так if err != nil { log.Println("Code exchange failed: " + err.Error()) json.NewEncoder(w).Encode(response) return } Но ошибок нет. Также я пробовал отправлять запросы с параметрами вместо заголовков, но результат был таким же.

Sergey 11.06.2019 10:33
Ответ принят как подходящий

Я нашел ответ. Это была моя вина. Структура, которая получает результат, выглядела так

type AuthContent struct {
    ID            string `json:"id"`
    Email         string `json:"email"`
    VerifiedEmail bool   `json:"verified_email"`
    Picture       string `json:"picture"`
}

Вот почему в ответе нет таких полей, как имя.

Другие вопросы по теме