Social Login with Phoenix 1.5

Sis Ccr
3 min readDec 10, 2020
google facebook login

Authentication is always hard for someone new in the field. But once we do it, Oh.. It feels good.

I had experience with social authentication in mobile application. So I had some faint concept, But this is my first time doing social authentication with web. I did got into unexpected handshake errors which was really hard to debug. Will tell about this at the end. First let’s get started.

First let’sueberauth_facebook and ueberauth_google as dependency

def deps do
[{:ueberauth_facebook, "~> 0.8"},
{:ueberauth_google, "~> 0.10"}]end

mix deps.get

Then configured ueberauth for facebook strategy in config.exs . The scopes field will appear on the facebook login window asking for permission.

config :ueberauth, Ueberauth,   providers: [        facebook: {Ueberauth.Strategy.Facebook, 
[default_scope: "email,public_profile"]},
google: {Ueberauth.Strategy.Google,
[default_scope: "email profile"]}
]

added uberauth configuration with facebook app id and secret

config :ueberauth, Ueberauth.Strategy.Facebook.OAuth,   client_id: System.get_env("FACEBOOK_CLIENT_ID"),   client_secret: System.get_env("FACEBOOK_CLIENT_SECRET")
config :ueberauth, Ueberauth.Strategy.Google.OAuth, client_id: System.get_env("GOOGLE_CLIENT_ID"), client_secret: System.get_env("GOOGLE_CLIENT_SECRET")

then lets add following in router.ex this will provide path like “/auth/facebook” or “/auth/google” which we will use later in template.

scope "/auth", MyApp do
pipe_through([:browser])
get("/:provider", AuthController, :request)
get("/:provider/callback", AuthController, :callback)
post("/:provider/callback", AuthController, :callback)
post("/logout", AuthController, :delete)
end

I created AuthController inside app_web>controller>auth_controller.ex

and added delete function which will be used to logout from our application.

and two callback function to handle the response from the facebook or google or other oauth system. It will be either failure or success.

don’t forget to add plug Uberauth as it intercepts the request and takes over the authenitcation flow.

In success We simply create account with our Context module called Accounts with Model User. Here is my user model generated with

mix phx.gen.html Accounts User users email uid name avatar

Tailwind.Accounts.find_or_create(auth) simply checkes if the user with given email exists in database or not, If It exists then it return the same user else It creates user and returns it. Here is the extra logic that I added in my accounts.ex.

make sure to add these lines at the top:

defmodule Tailweind.Accounts do
require Logger
alias Ueberauth.Auth
...

Lets add the following in pageController, If there is current user then we render it to view.

def index(conn, _params) do    render(conn, "index.html", current_user: get_session(conn, :current_user))end

and for page.index.html

page template

we should be able to login and logout with facebook and login now. There are some setting that we need to do in Goolge and Facebok developer application.

specially in facebook its easy to forget to set domain as localhost in the basic setting of facebook. If application is in development, there is no need to add the oAuth auth redirection uris. For live we need to add that too.

Since I am on current latest version of elixir and otp, Elixir 1.11.2 (compiled with Erlang/OTP 23) I had issue with some libraries where were not directly added to my mix deps. They were dependencies of the dependencies.If you also got those errors, its because not all libraries are updated to work with latest version of elixir. And I got stuck in one error that stated handshake_failed. Later I found out that It was because of Hackeney that was not compatible with my system. Luckily the fix was made in the Hackeny github master branch. hence solved by adding latest hackney from github in my mix.exs. override: true is necessary as it forces all of our dependencies to use this instead.

{:hackney, git: “https://github.com/benoitc/hackney.git", branch: “master”, override: true}

I hope this helps to any one Trying to integrate social authentication in phoenix.

--

--