Kapeusz

Kapeusz

Guardian with Uberauth Google

Hello, in my app I have been using Guardian for some time. However, I wanted to replace the current sign in with email and password to google auth. I have a problem setting this up. Right now, my code looks like:
First I added to config
Of course, all the config variables are filled in with, I think, correct information.

  config :my_app, MyAppWeb.Auth.Guardian,
    issuer: "my_app",
    secret_key: System.get_env("SESSION_SECRET_KEY")

  config :ueberauth, Ueberauth.Strategy.Google.OAuth,
    client_id: System.get_env("CLIENT_ID"),
    client_secret: System.get_env("CLIENT_SECRET"),
    redirect_uri: System.get_env("REDIRECT")

router.ex

  scope "/", MyAppWeb do
    pipe_through [:browser, :auth]

    get "/phoenix", PageController, :index

    get "/", SessionController, :new

    get "/:provider", SessionController, :request
    get "/:provider/callback", SessionController, :callback
    delete "/logout", SessionController, :delete
  end

session_controller.ex

defmodule MyAppWeb.SessionController do
  use MyAppWeb, :controller
  plug Ueberauth

  alias Ueberauth.Strategy.Helpers

  alias MyApp.Repo.Users
  alias MyApp.Repo.Schemas.User
  alias MyAppWeb.Auth.Guardian

  def new(conn, _params) do
    case Guardian.Plug.current_resource(conn) do
      nil ->
        conn
        |> put_root_layout({MyAppWeb.LayoutView, "login.html"})
        |> render("new.html")

      %User{} ->
        redirect(conn, to: Routes.dashboard_path(conn, :index))
    end
  end

  def request(conn, _params) do
    render(conn, "request.html", callback_url: Helpers.callback_url(conn))
  end

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

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    case Users.get_by_email(auth.info.email) do
      {:ok, %User{} = user} ->
        conn
        |> Guardian.Plug.put_current_resource(user)
        |> Guardian.Plug.sign_in(user, %{}, ttl: {2, :minute})
        |> redirect(to: Routes.dashboard_path(conn, :index))

      {:error, _} ->
        conn
        |> put_flash(:error, "Could not proceed, try again.")
        |> redirect(to: Routes.page_path(conn, :index))
    end
  end

  def delete(conn, _) do
    conn
    |> Guardian.Plug.sign_out()
    |> put_flash(:info, "You have been logged out!")
    |> redirect(to: "/")
  end
end

new.html.eex

<div class="flex flex-col justify-center items-center h-screen">
  <img src="/images/logo.svg" alt="MyApp" class="inline-block align-middle mb-4" />
  <div class="bg-gray-100 rounded-lg p-8 w-full max-w-md">
    <a class="button" href="<%= Routes.session_path(@conn, :request, "google") %>">
    <i class="fa fa-google"></i>
      Sign in with Google
    </a>
  </div>
</div>

request.html.eex

<h1>Log in with email / password</h1>

<p>
  Enter the information to simulate the authentication.
</p>

<%= form_tag @callback_url, method: "post" do %>
  <fieldset>
    <legend>Authentication Information</legend>

    <label for="email">Email</label>
    <input type="email" name="email" id="email" required value="<%= @conn.params["email"] %>" />

    <label for="password">Password</label>
    <input type="password" name="password" id="password" required />

    <label for="password_confirmation">Confirm Password</label>
    <input type="password" name="password_confirmation" id="password_confirmation" required />
  </fieldset>

  <input class="button" type="submit" value="Login" />
<% end %>

I’m not sure what I’m missing. At this moment, when I click on Sign in with Google I’m redirected to request.html.eex template.

I’d appreciate any suggestion/idea/help on how to make it work.

Thank you!

##update

I was wondering so long and just noticted that I have to add:
/auth/ part to the route.

First Post!

APB9785

APB9785

Creator of ECSx
def request(conn, _params) do
  render(conn, "request.html", callback_url: Helpers.callback_url(conn))
end

Here the request is sending to request.html.heex instead of your google OAuth app. Looks like a mock which only simulates making an OAuth request. For the real thing, you’ll want to let Ueberauth handle that request instead. There is a default request/2 function which will be used if you remove yours - that should get you going.

You only need to define request/2 manually if you have custom logic (such as saving state to the session). And in that case, it should call Ueberauth.run_request/4 instead of render/3

Last Post!

Kapeusz

Kapeusz

Thank you for the answer and the advice! I removed it and it still works!

Where Next?

Popular in Questions Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement