Problem when logging in to authentication page

I have made an authentication page following this article.

User creation works perfectly …
When creating the user I see that it can authenticate.

Then I log out of the application and try to login …
More to no avail.

The authentication page does not work, as if it did not validate the information (email/password).

Controller session:

defmodule GcallWeb.SessionController do
    use GcallWeb, :controller
  
    alias Gcall.Structure
    alias Gcall.Structure.User
  
    def new(conn, _params) do
      render(conn, "new.html")
    end
  
    def create(conn, %{"session" => auth_params}) do
      user = Structure.get_by_email(auth_params["email"])
      case Comeonin.Bcrypt.check_pass(user, auth_params["password"]) do
      {:ok, user} ->
        conn
        |> put_session(:current_user_id, user.id)
        |> put_flash(:info, "Conectado com sucesso.")
        |> redirect(to: Routes.page_path(conn, :index))
      {:error, _} ->
        conn
        |> put_flash(:error, "Houve um problema com seu email/senha")
        |> render("new.html")
      end
    end
  
    def delete(conn, _params) do
      conn
      |> delete_session(:current_user_id)
      |> put_flash(:info, "Deslogado com sucesso!")
      |> redirect(to: Routes.page_path(conn, :index))
    end
  end

Schema table user:

  alias Comeonin.Bcrypt
  schema "users" do
    field :dashboard, :string
    field :email, :string
    field :name, :string
    field :password, :string
    field :profile_id, :integer, default: 1
#    field :validate, :boolean, default: false

#    timestamps()
  end

  @doc false
  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :password, :email, :dashboard, :profile_id])
    |> validate_required([:name, :password, :email])
    |> unique_constraint(:email)
    |> update_change(:password, &Bcrypt.hashpwsalt/1)
  end

Template:

<h1>Sign in</h1>
<%= form_for @conn, Routes.session_path(@conn, :new), [as: :session], fn f -> %>
  <%= text_input f, :email, placeholder: "email" %>
  <%= password_input f, :password, placeholder: "password" %>
  <%= submit "Sign in" %>

<% end %>

Debug:

info] POST /login
[debug] Processing with GcallWeb.SessionController.create/2
  Parameters: %{"_csrf_token" => "LiBKdjgTUTk6U0QVACo3IWA+H0NFK0QFOl0AypikB91a7ugb4gt37SqG", "_utf8" => "✓", "session" => %{"email" => "teste2@teste.com", "password" => "[FILTERED]"}}
  Pipelines: [:browser]
[debug] QUERY OK source="users" db=0.5ms
SELECT u0.`id`, u0.`dashboard`, u0.`email`, u0.`name`, u0.`password`, u0.`profile_id` FROM `users` AS u0 WHERE (u0.`email` = ?) ["teste2@teste.com"]
[info] Sent 200 in 1ms

What think it might be?
And how do I solve it?

hi, would you to follow this example :

  1. https://github.com/codenoid/phoenix-auth-example/blob/master/multi/lib/multi_web/helper/session.ex
  2. https://github.com/codenoid/phoenix-auth-example/blob/b7b28fbd2b317d2e64bed42dd0030e304cefd029/multi/lib/multi_web/endpoint.ex#L48
  3. https://github.com/codenoid/phoenix-auth-example/blob/56ee9dce2b41e67b064ec09a67a91c300d025dde/multi/lib/multi_web/controllers/page_controller.ex#L14

imho, i don’t know, your code looks more complicated for “User Authentication” tutorial

WHat do you mean by “does not work”? Do you see a message telling you that credentials were wrong, or does it produce a redirect to log you in but doesn’t actually log you in?

Also from a first glance it looks as if you are using an old version of comeonin

1 Like

By clicking “submit” the template
He just does not do anything.

Even with the wrong password or the correct password, nothing is generated.

As if it did not exist “create” in the “controller session”

I’m guessing, it’s related to
controller session(GcallWeb.SessionController)
case Comeonin.Bcrypt.check_pass(user, auth_params["password"])

image

You want to :create a session…

Correct, already tried to put until: create, to see if it would work.
But without success.

What do you mean byuntil: create?

Ps, have you actually checked whether or not Structure.get_by_email returns something or if it is nil?

Yes there is,
it returns me all the fields …

Controller:

      user = Structure.get_by_email(auth_params["email"])
      IO.inspect(user)
%Gcall.Structure.User{
  __meta__: #Ecto.Schema.Metadata<:loaded, "users">,
  dashboard: "",
  email: "teste2@teste.com",
  id: 4,
  name: "teste2@teste.com",
  password: "$2b$12$b7Jc/tF7.pjUJswRfTHxMum3hB3IMhrWYjaJtz",
  profile_id: 1
}

I do not know if it would help but I did some tests like that …

iex(21)> user = Gcall.Structure.get_by_email(“teste2@teste.com”)
[debug] QUERY OK source=“users” db=8.5ms decode=2.9ms queue=0.8ms
SELECT u0.id, u0.dashboard, u0.email, u0.name, u0.password, u0.profile_id FROM users AS u0 WHERE (u0.email = ?) [“teste2@teste.com”]
%Gcall.Structure.User{
meta: ecto.Schema.Metadata<:loaded, “users”>,
dashboard: “”,
email: “teste2@teste.com”,
id: 4,
name: “teste2@teste.com”,
password: “$2b$12$b7Jc/tF7.pjUJswRfTHxMum3hB3IMhrWYjaJtz”,
profile_id: 1
}
iex(22)> user = Gcall.Structure.get_by_email(“teste2@teste.com”)
[debug] QUERY OK source=“users” db=1.2ms queue=0.2ms
SELECT u0.id, u0.dashboard, u0.email, u0.name, u0.password, u0.profile_id FROM users AS u0 WHERE (u0.email = ?) [“teste2@teste.com”]
%Gcall.Structure.User{
meta: ecto.Schema.Metadata<:loaded, “users”>,
dashboard: “”,
email: “teste2@teste.com”,
id: 4,
name: “teste2@teste.com”,
password: “$2b$12$b7Jc/tF7.pjUJswRfTHxMum3hB3IMhrWYjaJtz”,
profile_id: 1
}
iex(23)> Comeonin.Bcrypt.check_pass(user, “teste2@teste.com”)
{:error, “no password hash found in the user struct”}
iex(24)> Comeonin.Bcrypt.check_pass(user, “$2b$12$b7Jc/tF7.pjUJswRfTHxMum3hB3IMhrWYjaJtz”)
{:error, “no password hash found in the user struct”}
iex(25)> Comeonin.Bcrypt.check_pass(user, “teste2@teste.com”)

Unless you set the :hash_key option when calling the comeonin functions, it will use the :password_hash field.

So either rename your field or use the aforementioned option.

How would I be able to put the hash_key inside the auth_params?

Unmodified:

    def create(conn, %{"session" => auth_params}) do
      user = Structure.get_by_email(auth_params["email"])
      case Comeonin.Bcrypt.check_pass(user, auth_params["password"]) do
      {:ok, user} ->
        conn
        |> put_session(:current_user_id, user.id)
        |> put_flash(:info, "Conectado com sucesso.")
        |> redirect(to: Routes.page_path(conn, :index))
      {:error, _} ->
        conn
        |> put_flash(:error, "Houve um problema com seu email/senha")
        |> render("new.html")
      end
    end

With modification?

def create(conn, %{"session" => auth_params}) do
  user = Structure.get_by_email(auth_params["email"])
  case Comeonin.Bcrypt.check_pass(user, hash_key: :password) do
  {:ok, user} ->
    conn
    |> put_session(:current_user_id, user.id)
    |> put_flash(:info, "Conectado com sucesso.")
    |> redirect(to: Routes.page_path(conn, :index))
  {:error, _} ->
    conn
    |> put_flash(:error, "Houve um problema com seu email/senha")
    |> render("new.html")
  end
end

It did not work very well.

Of course you still need to pass a password.

I moved to
Comeonin.Bcrypt.check_pass(user, auth_params["password"], hash_key: :password)

Manually it is giving.

iex(87)> Comeonin.Bcrypt.check_pass(user, "teste11@teste11.com", hash_key: :password)
{:error, "invalid password"}

without success, thank you anyway.
I’ll keep looking here.

The code in iex is different to what you say in your first sentence. Please try with the code from your first sentence again.

Or is the users password actually it’s email address?

When I run the direct command, this problem happens …
That’s why I had to change.

iex(112)> Comeonin.Bcrypt.check_pass(user, auth_params["password"], hash_key: :password)
** (CompileError) iex:112: undefined function auth_params/0
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    (stdlib) lists.erl:1355: :lists.mapfoldl/3

the password actually and the email address

Then use the literal password. Or is the email address the literal password?

The password and the same email address

user: teste11@teste11.com
password: teste11@teste11.com

From what I can see so far, it should actually work…

Can you share the code?