rickmutua
Argument error whenever I try to login
[info] POST /api/sessions
[debug] Processing with Chatty.SessionController.create/2
Parameters: %{"email" => "email@gmail.com", "password" => "[FILTERED]"}
Pipelines: [:api]
[debug] QUERY OK source="users" db=2.1ms
SELECT u0."id", u0."email", u0."first_name", u0."last_name", u0."username", u0."phone", u0."password_hash", u0."is_admin", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."email" = $1) ["email@gmail.com"]
[info] Sent 500 in 5ms
[error] #PID<0.624.0> running Chatty.Endpoint (cowboy_protocol) terminated
Server: localhost:4000 (http)
Request: POST /api/sessions
** (exit) an exception was raised:
** (ArgumentError) argument error
:erlang.apply(%Chatty.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, email: "email@gmail.com", first_name: "first", id: 1, inserted_at: ~N[2018-07-02 18:33:29.885849], is_admin: false, last_name: "last", password: nil, password_hash: "$argon2i$v=19$m=256,t=1,p=1$lxRElye2Y8Fb92yIkqqqXw$UTfq1T37XQEGhRgJFDXlwqCjd0uuN0H8RxRVJX5lIzo", phone: "number", updated_at: ~N[2018-07-02 18:33:29.887999], username: "username"}, :config, [])
(guardian) lib/guardian.ex:776: Guardian.token_module/1
(guardian) lib/guardian.ex:576: Guardian.encode_and_sign/4
(guardian) lib/guardian/plug.ex:179: Guardian.Plug.sign_in/5
(chatty) web/controllers/api/session_controller.ex:10: Chatty.SessionController.create/2
(chatty) web/controllers/api/session_controller.ex:1: Chatty.SessionController.action/2
(chatty) web/controllers/api/session_controller.ex:1: Chatty.SessionController.phoenix_controller_pipeline/2
(chatty) lib/chatty/endpoint.ex:1: Chatty.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
(chatty) lib/chatty/endpoint.ex:1: Chatty.Endpoint.plug_builder_call/2
(chatty) lib/plug/debugger.ex:102: Chatty.Endpoint."call (overridable 3)"/2
(chatty) lib/chatty/endpoint.ex:1: Chatty.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /home/erick/Desktop/second/api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
What could be the issue?
below is session_controller file:
defmodule Chatty.SessionController do
use Chatty.Web, :controller
alias Chatty.User
def create(conn, params) do
case authenticate(params) do
{:ok, user} ->
new_conn = Guardian.Plug.sign_in(conn, user, :access)
jwt = Guardian.Plug.current_token(new_conn)
new_conn
|> put_status(:created)
|> render("show.json", user: user, jwt: jwt)
:error ->
conn
|> put_status(:unauthorized)
|> render("error.json")
end
end
def delete(conn, _) do
jwt = Guardian.Plug.current_token(conn)
Guardian.revoke!(jwt)
conn
|> put_status(:ok)
|> render("delete.json")
end
def refresh(conn, _params) do
user = Guardian.Plug.current_resource(conn)
jwt = Guardian.Plug.current_token(conn)
{:ok, claims} = Guardian.Plug.current_claims(conn)
case Guardian.refresh!(jwt, claims, %{ttl: {30, :days}}) do
{:ok, new_jwt, _new_claims} ->
conn
|> put_status(:ok)
|> render("show.json", user: user, jwt: new_jwt)
{:error, _reason} ->
conn
|> put_status(:unauthorized)
|> render("forbidden.json", error: "Not authenticated")
end
end
def unauthenticated(conn, _params) do
conn
|> put_status(:forbidden)
|> render(Chatty.SessionView, "forbidden.json", error: "Not Authenticated")
end
defp authenticate(%{"email" => email, "password" => password}) do
user = Repo.get_by(Chatty.User, email: String.downcase(email))
case check_password(user, password) do
true -> {:ok, user}
_ -> :error
end
end
defp check_password(user, password) do
case user do
nil -> Comeonin.Argon2.dummy_checkpw()
_ -> Comeonin.Argon2.checkpw(password, user.password_hash)
end
end
end
and below is the user_controller file:
defmodule Chatty.UserController do
use Chatty.Web, :controller
alias Chatty.User
plug Guardian.Plug.EnsureAuthenticated, [handler: Chatty.SessionController] when action in [:rooms]
def create(conn, params) do
changeset = User.registration_changeset(%User{}, params)
case Repo.insert(changeset) do
{:ok, user} ->
new_conn = Guardian.Plug.sign_in(conn, user, :access)
jwt = Guardian.Plug.current_token(new_conn)
new_conn
|> put_status(:created)
|> render(Chatty.SessionView, "show.json", user: user, jwt: jwt)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(Chatty.ChangesetView, "error.json", changeset: changeset)
end
end
def delete(conn, %{"id" => id}) do
user = Repo.get!(User, id)
# Here we use delete! (with a bang) because we expect
# it to always work (and if it does not, it will raise).
Repo.delete!(user)
send_resp(conn, :no_content, "")
end
def rooms(conn, _params) do
current_user = Guardian.Plug.current_resource(conn)
rooms = Repo.all(assoc(current_user, :rooms))
render(conn, Chatty.RoomView, "index.json", %{rooms: rooms})
end
end
Most Liked
OvermindDL1
Just a question I always ask when I see someone using Guardian: What functionality are you needing of JWT that a normal Phoenix Token doesn’t give you? If none then you really really should not be using Guardian as it is quite a bit more heavy-weight and geared toward specific purposes.
NobbZ
:erlang.apply/3 is called with wrong kind of arguments.
Usually the first argument should be a module name.
But how this actually happened remains to be unknown until you show us some more code, especially the Chatty.SessionController.create/2 might be interesting.
NobbZ
According to the (sparse) documentation, the second parameter to Guardian.Plug.sign_in/5 has to be an atom, but user (which is the result of Repo.insert/1) is a struct, not an atom.
But as I said, documentation is very sparse, and I’m not sure if the @spec is actually correct. And I do not use Guardian as I find its usage a bit strange. It feels wrong to use Guardian.Plug anywhere outside of a plug call. But maybe thats just me.
OvermindDL1
Guardian is fantastic for JWT uses, but for any other case the built-in Phoenix.Token tends to be far more efficient, and there are some framework around that are built on it’s ideals all depending on what you are trying to accomplish. ![]()
Specifically ‘what’ are you doing, just specifying a login endpoint for a JSON API? Do you want to store the authorization as a returned token (easier use for things like curl), in the session (better for sitewide javascript API’s), or both?
OvermindDL1
Hmm, 30 days implies some kind of client-side storage for the token, are you using local storage? If you are using local storage how are you handling the security issues around storing secure data in it? If you are using cookies then why not just use Phoenix’s standard session handling (which is already secure)? How do you elapse such a token if someone needs to be force disabled or it is revealed or so? Etc…? 
So far I’m leaning to the standard Phoenix session handling should probably be used, but need more information… 







