Rjdlee
Rjdlee

Reputation: 779

Youtube API Invalid Grant and Required parameter is missing: grant_type

I'm having trouble authenticating with the Youtube API via OAuth. It gives me this error:

This is my CURL code:

curl -i -X POST "https://accounts.google.com/o/oauth2/token" \ -F 'code=CODE_FROM_MY_USER' \ -F 'client_id=MY_CLIENT_ID' \ -F 'client_secret=MY_CLIENT_SECRET' \ -F 'redirect_uri=http://localhost:8080/platform/youtubeCallback.html' \ -F 'grant_type=authorization_code'

This is my Go code and has been verified to work for the Soundcloud API.

func Auth(code string) err {
    v := url.Values{}
    v.Set("code", code)
    v.Set("client_id", "MY_CLIENT_ID")
    v.Set("client_secret", "MY_CLIENT_SECRET")
    v.Set("redirect_uri", "http://localhost:8080/platform/youtubeCallback.html")
    v.Set("grant_type", "authorization_code")

    params := strings.NewReader(v.Encode())

    req, err := http.NewRequest("POST", "https://accounts.google.com/o/oauth2/token", params)
    if err != nil {
        return err
    }
    req.Header.Add("Accept", "application/json")

    resp, err := c.Client.Do(req)
    if err != nil || resp.StatusCode != 200 {
        return err
    }

    json.NewDecoder(resp.Body).Decode(&c.Token)

    return nil
}

Upvotes: 2

Views: 1208

Answers (2)

notvitor
notvitor

Reputation: 86

It also works if you create a map[string][]string and pass it to url.Values like:

namesToSend := map[string][]string{
  "firstname":{Bob}
}
values := url.Values{}
values = namesToSend

Then in the .NewRequest() you pass it like you passed the params.

req, err := http.NewRequest("POST", "https://accounts.google.com/o/oauth2/token", values)
if err != nil {
    return err
}

Upvotes: 1

Rjdlee
Rjdlee

Reputation: 779

It turns out you need to define the content type:

req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

Upvotes: 2

Related Questions