Google Calendar API invalid_grant получает токен (Golang)

Я пытаюсь получить токен доступа для аутентификации пользователей с помощью Oauth2. Я использую в основном код, найденный на странице HOW-TO Google для использования Calendar API с golang. Проблема в том, что всякий раз, когда я пытаюсь получить токен, Google возвращает это:

Response: {
 "error" : "invalid_grant"
}

С ошибкой oauth2: cannot fetch token: 400 Bad Request

Как я уже сказал, я использую код, полученный из руководства Google, только слегка измененный в соответствии с моими потребностями.

//Somewhere...
authURL = config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)

//Somewhere else...
func getClient(ctx context.Context, config *oauth2.Config, code string) *http.Client {
    cacheFile := tokenCacheFile()

    tok, err := tokenFromFile(cacheFile)
    if err != nil {
        log.Printf("Google auth code not cached. Obtaining from the web...")
        tok, err = getTokenFromWeb(code) //This returns an error
        if err == nil {
            log.Printf("Got token!")
            saveToken("calendar-go-quickstart.json", tok)
        } else { //Prevent saving token when error
            log.Printf("Couldn't get OAUTH2 token! %s", err)
        }
    }
    return config.Client(ctx, tok)
}

Ошибка возникает в "getTokenFromWeb (code)" (если я правильно понял, code должна быть некоторой случайной строкой, независимо от ее значения, она просто должна быть такой же во время весь процесс). Это проблемный код:

func getTokenFromWeb(code string) (*oauth2.Token, error) {
    tok, err := config.Exchange(context.Background(), code)
    return tok, err
}

После выполнения я вижу эту ошибку. Я даже получаю ту же ошибку при попытке скопировать и вставить собственный код Google!
Есть идеи? Я действительно не могу найти решение в Интернете.

Дополнительные сведения: использование веб-фреймворка IRIS; используя последнюю версию API календаря Google; используя последнюю версию Golang; Я создал идентификатор клиента для OAuth2 в Google Cloud Console; У веб-сайта есть доверенный сертификат SSL; прослушивает порт 80 (HTTP) и 4433 (HTTPS);


person Axel Montini    schedule 03.08.2017    source источник


Ответы (1)


Вот пример Google:

// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
  authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
  fmt.Printf("Go to the following link in your browser then type the "+
"authorization code: \n%v\n", authURL)

  var code string
  if _, err := fmt.Scan(&code); err != nil {
    log.Fatalf("Unable to read authorization code %v", err)
  }
  ...
}

code - это код авторизации, который выдается пользователю после перехода по отображаемой ссылке. fmt.Scan() будет сканировать ввод от пользователя.

Если вы собираетесь действовать от имени другого пользователя, вам придется сделать что-то похожее на этот пример. Если вы действуете только как вы, вы сможете пройти аутентификацию как себя без кода.

В любом случае code не может быть случайной строкой.

person Gavin    schedule 03.08.2017
comment
А, значит, он отправлен клиенту .. Но как мне его получить? Я предполагаю, что он отправляется на веб-сервер как параметр URL через запрос GET, поэтому мне нужно просто прочитать его из запроса пользователя, когда он будет перенаправлен обратно ?. Проверю как можно скорее, параметры честно не проверял. - person Axel Montini; 03.08.2017
comment
Спасибо, после повторной попытки я вижу, что код отправляется как параметр запроса. Теперь у меня другая проблема. (Редактирую вопрос прямо сейчас) - person Axel Montini; 04.08.2017
comment
перед редактированием, нормально ли, что код остается в строке URL и обновляется каждый раз, когда я нажимаю на элемент ‹a› html? Это выглядит странно, особенно потому, что я не обмениваюсь кодом с Google после аутентификации пользователя. Не только это, но и путь URL-адреса не меняется (я нажимаю <a href="/somepage">Go here</a>, но URL-адрес остается https://myside.com?state=state-token&code=c/odeThatChangesEveryTime) - person Axel Montini; 04.08.2017