OAuth2 and Facebook: Error validating client secret when exchanging code for AT

Does anyone here have an experience with OAuth2 and Facebook - https://github.com/scrogson/oauth2? I get an “Error validating client secret” when exchanging code for access_token. I used this solution in different app 3 months ago and it worked (but I don’t have an access to code now - so I can miss something really simple here).

When I try to exchange it manually (I send client_id, client_secret, request_uri and code to https://graph.facebook.com/v2.8/oauth/access_token) It works - I get the token (and user information later).

Here is what I have:

The controller:

defmodule TheApp.AuthController do
      use TheApp.Web, :controller

      require Logger

      def callback(conn, %{"grant_type" => provider, "auth_code" => code}) do
        # Exchange an auth code for an access token
        client = get_token!(provider, code)
        Logger.info "See client #{inspect client}"
        .....
      end


      defp get_token!("facebook", code), do: Facebook.get_token!(code: code)

      .....


    end

Facebook strategy module:

defmodule Facebook do
  
  use OAuth2.Strategy

  require Logger

  alias OAuth2.Strategy.AuthCode

  defp config do
   [strategy: __MODULE__,
    site: "https://graph.facebook.com",
    authorize_url: "https://www.facebook.com/dialog/oauth",
    token_url: "/v2.8/oauth/access_token",
    client_id: "16......48",
    client_secret: "ed.......c2",
    redirect_uri: "http://localhost:4200/"]
  end

  def client do
    config()
    |> OAuth2.Client.new()
  end

  def get_token!(params \\ [], headers \\ []) do
    Logger.info "Comming params#{inspect params}"
    Logger.info "What's in client#{inspect client()}"

    OAuth2.Client.get_token!(client(), params)
  end

 # Strategy Callbacks

 def get_token(client, params, headers) do
   Logger.info "Get token client#{inspect client}"
   Logger.info "Get token params#{inspect params}"

   client
     |> put_header("Accept", "application/json")
     |> AuthCode.get_token(params, headers)
 end
end

And here is what I get from logger and response…

[info] Comming params [code: "AQ.....Fo"]

[info] What's in client 
%OAuth2.Client{authorize_url: "https://www.facebook.com/dialog/oauth", 
client_id: "16.....48", 
client_secret: "ed....c2", 
headers: [], params: %{}, 
redirect_uri: "http://localhost:4200/", 
site: "https://graph.facebook.com", 
strategy: Facebook, token: nil, token_method: :post, token_url: "/v2.8/oauth/access_token"}

[info] Get token client
%OAuth2.Client{authorize_url: "https://www.facebook.com/dialog/oauth", 
 client_id: "16....48", 
 client_secret: "ed....c2", 
 headers: [{"content-type", "application/x-www-form-urlencoded"}], 
 params: %{}, 
 redirect_uri: "http://localhost:4200/", 
 site: "https://graph.facebook.com", strategy: Facebook, token: nil, token_method: :post, token_url: "/v2.8/oauth/access_token"}

[info] Get token params[code: "AQ.....Fo"]

[debug] OAuth2 Provider Response %OAuth2.Response{body: %{"error" => %{
"code" => 1, "fbtrace_id" => "ESyv6tGcv3h", 
"message" => "Error validating client secret.", 
"type" => "OAuthException"}}, headers: [{"www-authenticate", "OAuth \"Facebook Platform\" \"invalid_request\" \"Error validating client secret.\""}, {"access-control-allow-origin", "*"}, {"pragma", "no-cache"}, {"cache-control", "no-store"}, {"facebook-api-version", "v2.8"}, {"expires", "Sat, 01 Jan 2000 00:00:00 GMT"}, {"content-type", "application/json"}, {"x-fb-trace-id", "ESyv6tGcv3h"}, {"x-fb-rev", "2761076"}, {"x-fb-debug", "K54xxXY3UZVUU/CjvXYePxrLNjaKvssc9MCaf0hGjTekGUHo7jnBBaG3UoKEHXagcDTsSQiNibwlX5rJB0MzXw=="}, {"date", "Sat, 31 Dec 2016 12:57:49 GMT"}, {"connection", "keep-alive"}, {"content-length", "115"}], 
status_code: 400}

So I found the problem myself. Everything was configured and set properly. Client_id, client_secret and redirect_uri was correct.

The problem was that I miss that you have to add client_secret to get_token function again as I see it comming when logging “client” (you can see it in log). It’s kind of misleading. I describe it better on github.

Hope this could help someone.

1 Like