Я пытаюсь использовать 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_token и проверил его через jwt.io, я увидел все нужные мне данные. Но я не понимаю, что не так. Я думал, что информация о профиле должна быть получена через запрос API, например req, err := http.NewRequest("GET", <endPoint>, nil) gresponse, err := http.DefaultClient.Do(req)
. В этом примере используется только стандартная библиотека go, а gresponse
содержит полный http-ответ, не так ли? Почему в ответе нет нужных мне полей?
googleOauthConfig.Exchange(oauth2.NoContext, code)
http.DefaultClient.Do
ioutil.ReadAll(gresponse.Body)
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 }
Но ошибок нет. Также я пробовал отправлять запросы с параметрами вместо заголовков, но результат был таким же.
Я нашел ответ. Это была моя вина. Структура, которая получает результат, выглядела так
type AuthContent struct {
ID string `json:"id"`
Email string `json:"email"`
VerifiedEmail bool `json:"verified_email"`
Picture string `json:"picture"`
}
Вот почему в ответе нет таких полей, как имя.
попробуйте взять токен id и поместить его в jwt.io. Gtoken также должен содержать токен id. Мне интересно, если ваша библиотека просто неправильно анализирует ответ.