Json (UndefinedFunctionError)尝试登录到phx/elixir API时

Json (UndefinedFunctionError)尝试登录到phx/elixir API时,json,elixir,phoenix-framework,Json,Elixir,Phoenix Framework,我正在使用用Elixir编写的phoenix框架构建一个API。我现在可以使用Postman应用程序创建一个用户。API将返回201响应 但是,当我尝试使用新创建的用户登录时,API会发送一个500响应 我得到了以下线索 [info] Running KegCopRAPI.Web.Endpoint with Cowboy using http://0.0.0.0:4000 [info] POST /api/users [debug] Processing with KegCopRAPI.Web.

我正在使用用Elixir编写的phoenix框架构建一个API。我现在可以使用Postman应用程序创建一个用户。API将返回201响应

但是,当我尝试使用新创建的用户登录时,API会发送一个500响应

我得到了以下线索

[info] Running KegCopRAPI.Web.Endpoint with Cowboy using http://0.0.0.0:4000
[info] POST /api/users
[debug] Processing with KegCopRAPI.Web.UserController.create/2
  Parameters: %{"user" => %{"email" => "chris@example.com", "password" => "[FILTERED]", "username" => "chris"}}
  Pipelines: [:api]
[debug] QUERY OK db=2.8ms
INSERT INTO "accounts_users" ("email","encrypted_password","username","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" ["chris@example.com", "$2b$12$t1MvizA5fNhSvCald/jctedwvvtlI0jbY/s4W75dD/YwKiaJmZYXS", "chris", {{2017, 5, 10}, {21, 20, 28, 896254}}, {{2017, 5, 10}, {21, 20, 28, 903416}}]
[info] Sent 201 in 434ms
[info] OPTIONS /api/sessions
[info] Sent 204 in 37µs
[info] POST /api/sessions
[debug] Simple CORS request from Origin 'http://localhost:3000' is allowed
[info] Sent 500 in 16ms
[error] #PID<0.392.0> running KegCopRAPI.Web.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /api/sessions
** (exit) an exception was raised:
    ** (UndefinedFunctionError) function KegCopRAPI.Web.SessionController.init/1 is undefined (module KegCopRAPI.Web.SessionController is not available)
        KegCopRAPI.Web.SessionController.init(:create)
        (kegcopr_api) lib/kegcopr_api/web/router.ex:1: anonymous fn/1 in KegCopRAPI.Web.Router.__match_route__/4
        (phoenix) lib/phoenix/router.ex:277: Phoenix.Router.__call__/1
        (kegcopr_api) lib/kegcopr_api/web/endpoint.ex:1: KegCopRAPI.Web.Endpoint.plug_builder_call/2
        (kegcopr_api) lib/plug/debugger.ex:123: KegCopRAPI.Web.Endpoint."call (overridable 3)"/2
        (kegcopr_api) lib/kegcopr_api/web/endpoint.ex:1: KegCopRAPI.Web.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /opt/elixir/kegcopr_api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

非常感谢您的帮助。

在第一段代码中,您可以看到您的路由器找不到KegCopRAPI.Web.SessionController,但您有KegCopRAPI.SessionController

这个Web名称空间最近在Phoenix v1.3.0-rc.0中引入,以强调您正在更改应用程序的Web层

此外,您的控制器代码是有效的,但您可以使用with子句和action\u回退宏对其进行调整,使其更符合Phoenix 1.3的最新版本。

您告诉路由器使用KegCopRAPI.Web.SessionController,但您的控制器是KegCopRAPI.SessionController请注意缺少Web。由于打字错误,投票关闭。
defmodule KegCopRAPI.SessionController do
  use KegCopRAPI.Web, :controller
  # Note: the below statement squelched the warning about not finding the Repo.
  alias KegCopRAPI.Repo

  def create(conn, params) do
    case authenticate(params) do
      {:ok, user} ->
        new_conn = Guardian.Plug.api_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.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(KegCopRAPI.SessionView, "forbidden.json", error: "Not Authenticated")
  end

  defp authenticate(%{"email" => email, "password" => password}) do
    user = Repo.get_by(KegCopRAPI.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.Bcrypt.dummy_checkpw()
      _ -> Comeonin.Bcrypt.checkpw(password, user.password_hash)
    end
  end
end