我使用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
session_controller.ex 如下所示,
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
非常感谢任何和所有帮助。
答案 0 :(得分:1)
在第一个代码段中,您可以看到您的路由器无法找到KegCopRAPI.Web.SessionController
,但您有KegCopRAPI.SessionController
。
最近在Phoenix v1.3.0-rc.0中引入了这个Web
命名空间,以强调您正在改变应用程序的Web层。
此外,您的控制器代码有效,但您可以使用with
子句和action_fallback
宏来调整它以使Phoenix 1.3更新。