Problem with non-SSL http post back?

I’m hitting an error and my view is because its not being returned to an secure location (https://) on my local host. I read an article about challenges with secure connections and ran mix deps.update hackney, but I still get the same erro.

The error I receive is;

[error] #PID<0.2948.0> running PlatformWeb.Endpoint (connection #PID<0.2947.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: POST /graphql
** (exit) an exception was raised:
    ** (WithClauseError) no with clause matching: {:error, {:options, {:sslv3, {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1, :sslv3]}}}}
        (platform 0.1.0) lib/platform/accounts/accounts.ex:769: Platform.Accounts.fetch_linkedin_credential/1

The code I have is;

def fetch_linkedin_credential(params) do
    with {:ok, %{"access_token" => access_token} = auth_data} <-
           LinkedIn.Oauth2.exchange_auth_code(params.code),
         credential = %{access_token: access_token},
         {:ok, profile_data} <- LinkedIn.fetch_profile(credential),
         {:ok, primary_contact_data} <- LinkedIn.fetch_primary_contact(credential) do
      data =
        auth_data
        |> Map.put("linkedin_uid", profile_data["id"])
        |> Map.put("first_name", profile_data["localizedFirstName"])
        |> Map.put("last_name", profile_data["localizedLastName"])
        |> Map.put("profile_image_url", LinkedIn.get_profile_image(profile_data))
        |> Map.put("email", LinkedIn.get_email_from_primary_contact(primary_contact_data))

      {:ok, data}
    else
      {:error, %{"error_description" => message}} ->
        Task.Supervisor.async_nolink(Platform.TaskSupervisor, fn ->
          Sentry.capture_message(
            "auth_linkedin_error",
            extra: %{error: message}
          )
        end)

        {:error, message}
    end

I would recommend you to use HTTPS for localhost development as per official docs:

https://hexdocs.pm/phoenix/using_ssl.html#ssl-in-development

SSL in Development

If you would like to use HTTPS in development, a self-signed certificate can be generated by running: mix phx.gen.cert. This requires Erlang/OTP 20 or later.

With your self-signed certificate, your development configuration in config/dev.exs can be updated to run an HTTPS endpoint:

config :my_app, MyApp.Endpoint,
 ...
 https: [
   port: 4001,
   cipher_suite: :strong,
   keyfile: "priv/cert/selfsigned_key.pem",
   certfile: "priv/cert/selfsigned.pem"
 ]

This can replace your http configuration, or you can run HTTP and HTTPS servers on different ports.

Force SSL

In many cases, you’ll want to force all incoming requests to use SSL by redirecting HTTP to HTTPS. This can be accomplished by setting the :force_ssl option in your endpoint configuration. It expects a list of options which are forwarded to Plug.SSL. By default it sets the “strict-transport-security” header in HTTPS requests, forcing browsers to always use HTTPS. If an unsafe (HTTP) request is sent, it redirects to the HTTPS version using the :host specified in the :url configuration. For example:

config :my_app, MyApp.Endpoint,
 force_ssl: [rewrite_on: [:x_forwarded_proto]]

To dynamically redirect to the host of the current request, set :host in the :force_ssl configuration to nil.

config :my_app, MyApp.Endpoint,
 force_ssl: [rewrite_on: [:x_forwarded_proto], host: nil]

In these examples, the rewrite_on: key specifies the HTTP header used by a reverse proxy or load balancer in front of the application to indicate whether the request was received over HTTP or HTTPS. For more information on the implications of offloading TLS to an external element, in particular relating to secure cookies, refer to the Plug HTTPS Guide. Keep in mind that the options passed to Plug.SSL in that document should be set using the force_ssl: endpoint option in a Phoenix application.

The first time you use the certificate on the browser it will show you a warning and you will need to click through the steps to add an exception for that particular certificate. Afterwards all should work as usual.

1 Like

@Exadra37 thanks. I’ve added a cert, and configured the dev.exs in the config directory, but I’m getting the same error.

As its the backend API layer, the frontend operates on port 3000 and isn’t forced to HTTPS. The call is going from the HTTP frontend to LinkedIn which is then returning back to the port I push it too. That said when I hit the https://localhost:4000 directly, I get SSL errors which relates to it not being a proper cert but no advanced option to by pass it… happens on FF, Edge, Chrome and Safari…

Set the frontend to also work in https.

Some third party services don’t work with localhost urls, therefore you need to switch to use local site names from the Linux /etc/hosts file or whatever equivalent in your OS.

My hosts file:

# OMMITED

# Custom host records are listed here.

127.0.0.1 tasks-todo.io
127.0.0.1 app.local
127.0.0.1 app2.local
127.0.0.1 app3.local
127.0.0.1 app4.local
127.0.0.1 app5.local
127.0.0.1 app6.local
127.0.0.1 links.local
127.0.0.1 notes.local
127.0.0.1 articles.local
127.0.0.1 videos.local
127.0.0.1 chat.local
127.0.0.1 todos.local
127.0.0.1 til.local
127.0.0.1 faq.local

For example, the local domain tasks-todo.io is used by me in the form of tasks-todo.io:4000 to be able to use OAUTH2 authentication with a third party provider that doesn’t allow to redirect the frontend to a localhost:port url.

Remember to replace localhost with the one you added to the hosts file in all places its used by your application and server running it.

  1. Check that the endpoint you are calling actually works.
  2. If it indeed works, check that you are running the latest version of Hackney if you happen to be running an older version and have recently upgraded Erlang/OTP to 23.

A self-signed certificate should raise a different error

You can fix your certificate warnings from phoenix by following these steps

Please clarify me on this. As per your code snippets you have the code which hits linkedIn in your backend right inside controller. Are you doing fetch request from your js files ?