Ошибка: invalid_request Отсутствует требуемый параметр: client_id в golang

У меня проблемы с аутентификацией с помощью Google OAuth2.

Я получил идентификатор клиента и секрет с консоли разработчика Google, и я придумал этот код:

package main

    import (
        "fmt"
        "golang.org/x/oauth2"
        "golang.org/x/oauth2/google"
        "io/ioutil"
        "net/http"
        "os"
    )

    const htmlIndex = '<html><body>
    <a href="/GoogleLogin">Log in with Google</a>
    </body></html>
    '

    func init() {
        // Setup Google example test keys
        os.Setenv("CLIENT_ID", "somrestring-otherstring.apps.googleusercontent.com")
        os.Setenv("SECRET_KEY", "alongcharachterjumble")
    }

    var (
        googleOauthConfig = &oauth2.Config{
            RedirectURL:  "http://127.0.0.1:8080/auth",  //defined in Google console
            ClientID:     os.Getenv("CLIENT_ID"),
            ClientSecret: os.Getenv("SECRET_KEY"),
            Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile",
                "https://www.googleapis.com/auth/userinfo.email"},
            Endpoint: google.Endpoint,
        }
        // Some random string, random for each request
        oauthStateString = "random"
    )

    func main() {
        http.HandleFunc("/", handleMain)
        http.HandleFunc("/GoogleLogin", handleGoogleLogin)
        http.HandleFunc("/GoogleCallback", handleGoogleCallback)
        fmt.Println(http.ListenAndServe(":8080", nil))
    }

    func handleMain(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, htmlIndex)
        fmt.Println("another request made")
    }

    func handleGoogleLogin(w http.ResponseWriter, r *http.Request) {
        url := googleOauthConfig.AuthCodeURL(oauthStateString)
        http.Redirect(w, r, url, http.StatusTemporaryRedirect)
    }

    func handleGoogleCallback(w http.ResponseWriter, r *http.Request) {
        state := r.FormValue("state")
        if state != oauthStateString {
            fmt.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state)
            http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
            return
        }

        code := r.FormValue("code")
        token, err := googleOauthConfig.Exchange(oauth2.NoContext, code)
        if err != nil {
            fmt.Println("Code exchange failed with '%s'\n", err)
            http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
            return
        }

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

        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        fmt.Fprintf(w, "Content: %s\n", contents)
    }

Но я получаю эту ошибку от google:

  1. Это ошибка.

Ошибка: invalid_request

Отсутствует требуемый параметр: client_id

Учить больше

Запросить информацию client_id = redirect_uri = http://127.0.0.1:8080/auth response_type = code scope = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email state = random

Что здесь не так? Как я могу это исправить?

0
источник поделиться
1 ответ

Сообщение об ошибке указывает, что ClientID не инициализирован.

Это выглядит в соответствии с кодом, так как объявления var выполняются перед функциями init.

Поэтому, когда ваш запрос var os.Getenv("CLIENT_ID") значение пустое, поскольку init еще не выполнен.

Из документации:

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

https://golang.org/ref/spec#Package_initialization

Чтобы исправить это, либо поместите строку непосредственно в инициализацию var, либо инициируйте инициализацию из init после установки значений.

Подобно:

var (
    googleOauthConfig *oauth2.Config
)

func init() {
     // init ENV
     // initialize the variable using ENV values
     googleOauthConfig = &oauth2.Config{ ... }
}

Кроме того, вы можете установить эти значения ENV на уровне ОС перед выполнением фактической программы Go.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос