facebookgooauth-2.0google-oauth

Unable to use package "golang.org/x/oauth2" to authenticate with facebook: "Missing redirect_uri parameter"


This code works:

func handleFacebookCallback(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")

////////////////////////////////////////////////////    
    Url, err := url.Parse(oauthConf.Endpoint.TokenURL)
    if err != nil {
        log.Fatal("Parse: ", err)
    }
    parameters := url.Values{}
    parameters.Add("client_id", oauthConf.ClientID)
    parameters.Add("client_secret", oauthConf.ClientSecret)
    parameters.Add("redirect_uri", "http://localhost:9090/oauth2callback")
    parameters.Add("code", code)
    Url.RawQuery = parameters.Encode()
    resp, err := http.Get(Url.String())

    if err != nil {
        fmt.Printf("Get: %s\n", err)
        http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
        return
    }
    defer resp.Body.Close()

But when I replace the part below the marker //////... with:

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

I get:

oauthConf.Exchange() failed with 'oauth2: cannot fetch token: 400 Bad Request Response: {"error":{"message":"Missing redirect_uri parameter.","type":"OAuthException","code":191,"fbtrace_id":"XXXX"}}'

Is the package golang.org/x/oauth2 unable to exchange a code for a token?


Solution

  • I found out what was missing. I apparently need to add the RedirectURLfield in the oauthConfig struct to get Exchange() to work properly. This is not the case for Slack or GitHub but apparently FB is slightly more picky.

    var oauthConf = &oauth2.Config{
            ClientID:     "YOUR_CLIENT_ID",
            ClientSecret: "YOUR_CLIENT_SECRET",
            RedirectURL:  "http://localhost:9090/oauth2callback", /* Fixed! */
            Scopes:       []string{"public_profile"},
            Endpoint:     facebook.Endpoint,
        }