Please add the Phoenix tag (as well as two other tags) when posting threads in this section. Thanks!
def sign_in_user(conn, %{"user" => user}) do
try do # Attempt to retrieve exactly one user from the DB, whose email matches the one provided with the login request
user = User
|> where(email: ^user.email)
|> Repo.one!
cond do
true ->
# Successful login, Encode a JWT
{ :ok, jwt, _ } = Guardian.encode_and_sign(user, :token)
auth_conn = Guardian.Plug.api_sign_in(conn, user)
jwt = Guardian.Plug.current_token(auth_conn)
{:ok, claims} = Guardian.Plug.claims(auth_conn)
auth_conn
|> put_resp_header("authorization", "Bearer #{jwt}")
|> json(%{access_token: jwt}) # Return token to the client
false -> # Unsuccessful login
conn
|> put_status(401)
|> render(StoryWeb.ErrorView, "401.json-api")
end
rescue
e ->
IO.inspect e
# Print error to the console for debugging
# Successful registration
sign_up_user(conn, %{"user" => user})
end
Pin operator would not work with dot notation. You should either assign the value to the local variable upfront and pin it, or simply destructure user in the function clause.
def sign_in_user(conn, %{"user" => user}) do
email = user.email
user = User |> where(email: ^email) |> Repo.one!
...
or
def sign_in_user(conn, %{"user" => %{email: email}}) do
user = User |> where(email: ^email) |> Repo.one!
...
For future readers: the issue with this code is that the pin operator isn’t needed here - the where is expecting a plain keyword list: where(email: user.email)
This is different from the behavior of where inside a from expression, because from manipulates the supplied AST a lot.