Ueberauth + Phx 1.3 Example

I’ve been working through the Phx 1.3 docs and have been upgrading an that uses Ueberauth OAuth strategies + Guardian for authentication and tokens, but I’ve been running into some errors with callback/changesets after shifting over to the contexts paradigm

Can anyone point to a good implementation/example of Ueberauth OAuth or Identity in Phoenix 1.3?

As for my error, if any of ya’ll are interested…

I’ve created my schema and account logic using mix phx.gen.context Accounts Users etc etc, and I’m not quite sure of how to alias my Accounts Users schema and logic and how to operate on it in my controller, or if I shouldn’t implement it on my controller anymore…

I currently alias it in my controller as:

  alias Auth.Accounts.User

in my AuthController, but on mix ecto.create I get the following error:

== Compilation error in file lib/auth_web/controllers/auth_controller.ex ==
** (CompileError) lib/auth_web/controllers/auth_controller.ex:13: Auth.Accounts.User.__struct__/1 is undefined, cannot expand struct Auth.Accounts.User
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    lib/auth_web/controllers/auth_controller.ex:7: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

Full controller code:

defmodule Auth.AuthController do
  use AuthWeb, :controller
  plug Ueberauth

  alias Auth.Accounts.User

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, params) do
    IO.inspect(conn)
    user_params = %{
      token: auth.credentials.token,
      email: auth.info.email,
      provider: auth.provider}
    changeset = User.changeset(%User{}, user_params)

    signin(conn, changeset)
  end

  def signout(conn, _params) do
    conn
    |> configure_session(drop: true)
    |> redirect(to: page_path(conn, :index))
  end

  defp signin(conn, changeset) do
    case insert_or_update_user(changeset) do
      {:ok, user} ->
        conn
        |> put_flash{:info, "Welcome!"}
        |> put_session(:user_id, user.id)
        |> redirect(to: page_path(conn, :index))
      {:error, _reason} ->
        conn
        |> put_flash(:error, "A Sign-in Error Occurred")
        |> redirect(to: page_path(conn, :index))
    end
  end

  defp insert_or_update_user(changeset) do
    case Repo.get_by(User, email: changeset.changes.email) do
      nil ->
        Repo.insert(changeset)
      user ->
        {:ok, user}
    end
  end

end
1 Like

Not sure if it is related, but how did You create your controller?

lib/auth_web/controllers/auth_controller.ex

You do not use the same name auth_web, but Auth

defmodule Auth.AuthController

shouldn’t be ?

defmodule AuthWeb.AuthController

and maybe You can show the Auth.Accounts.User file

2 Likes

Good catch! Should definitely be AuthWeb.AuthController. Thank you!

Still getting that same error

Regarding Account/Accounts I did mix.gen.context Accounts rather than Account, that was a typo in my original post, not in the controller. Corrected Accounts in my original post

It is difficult to answer without seing the user file, as the error is pointing to it, and it is not being seen as a struct.

Also, I might advise to hide user details by calling functions on the accounts context.

eg:

alias Auth.Accounts
changeset = Accounts.user_changeset

You can put changeset creation inside Accounts, even if You delegate to Auth.Accounts.User at the end.

This way You hide implementation details.

1 Like

I’m using Ueberauth and a few strategies in 1.3 just fine, would really need to see Auth.Accounts.User.

My original issue was that I generated everything with Accounts Users user, so I was using Accounts.User when I should have been using Accounts.Users, which is awful syntax. Also, had redundant logic between my accounts.ex and my auth_controller…

Really, I was able to sort everything out after going through the Contexts Guide in the Phoenix 1.3 docs

Thank you for reading and replying, Overmind and Koko !