Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot authenticate with client-initiated flow, fb signed request cookie is not read by ueberauth #41

Open
yourtallness opened this issue Mar 23, 2018 · 1 comment

Comments

@yourtallness
Copy link

yourtallness commented Mar 23, 2018

Hello,

While navigating to /auth/facebook works fine, I cannot make a client side flow work properly.
The reason for preferring a client side flow is to authorize FB in a popup so that the user never leaves our site.

I have initialized the FB JS app with the app id and cookie set to true.

    FB.init({
        appId      : appId,
        cookie     : true,
        xfbml      : true,
        version    : 'v2.12'
    });

However in my case the failure callback is getting called on my auth controller because ueberath cannot find the code.

    def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
      conn
      |> put_flash(:error, "Failed to authenticate.")
      |> redirect(to: "/")
    end

Line of code in current project

The issue is that ueberauth_facebook does not read the code from the fb signed request cookie in case it cannot find it in the params.

Omniauth extracts the authorization code from the cookie like this:

omniauth code that extracts code either from params or cookie

omniauth cookie parsing logic

The cookie value is Base64 encoded and signed with HMAC-SHA256.

Could this be done here as well to support the client-initiated flow?

Omniauth client side flow documentation

Thanks in advance,

Mark

@yourtallness yourtallness changed the title Cannot authenticate with client-initiated flow Cannot authenticate with client-initiated flow, seems cookie is not read by ueberauth Mar 23, 2018
@yourtallness yourtallness changed the title Cannot authenticate with client-initiated flow, seems cookie is not read by ueberauth Cannot authenticate with client-initiated flow, fb signed request cookie is not read by ueberauth Mar 23, 2018
@yourtallness
Copy link
Author

I tried to pre-pend a Plug that would extract the code from the cookie and redirect to /auth/facebook/callback?code=<extracted_code>.

defmodule MyAppWeb.Plugs.ParseFbsrCookie do
    import Plug.Conn
    
    require IEx

    def init(_params) do
    end
  
    def call(conn, _params) do
        if conn.params["code"] == nil do
            fbsr = conn.cookies["fbsr_#{System.get_env("FACEBOOK_APP_ID")}"]
            if fbsr do
                [signature, encoded_payload] = String.split(fbsr, ".")
                # TODO: validate signature
                decoded_payload = Poison.decode!(Base.decode64!(encoded_payload))
                code = decoded_payload["code"]
                if code do
                    conn
                    |> Phoenix.Controller.redirect(to: "#{conn.request_path}?code=#{code}")
                    |> halt()
                end
            end
        else
            conn
        end
    end
end

However this still fails because the jssdk iniated flow does not specify a redirect_uri and there is a mismatch:

OAuth "Facebook Platform" "invalid_code" "Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request"

Omniauth handles this by setting the request_uri to ''.

There is also the question of the state params.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant