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")


  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


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 ->
        |> put_root_layout({MyAppWeb.LayoutView, "login.html"})
        |> render("new.html")

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

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

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

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

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

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


<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


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

  Enter the information to simulate the authentication.

<%= form_tag @callback_url, method: "post" do %>
    <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 />

  <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!


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

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

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

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