Elixir Plug.Conn.resp/3中没有匹配的函数子句
在使用Guardian对JWT令牌验证GET请求后,我尝试使用JSON进行响应 我的测试:Elixir Plug.Conn.resp/3中没有匹配的函数子句,elixir,phoenix-framework,guardian,Elixir,Phoenix Framework,Guardian,在使用Guardian对JWT令牌验证GET请求后,我尝试使用JSON进行响应 我的测试: describe "Show user if authenticated" do setup %{conn: conn} do {:ok, %User{} = user} = Riders.create_user(@create_attrs) {:ok, jwt, claims} = Bikefit.Guardian.encode_and_sign(user)
describe "Show user if authenticated" do
setup %{conn: conn} do
{:ok, %User{} = user} = Riders.create_user(@create_attrs)
{:ok, jwt, claims} = Bikefit.Guardian.encode_and_sign(user)
IO.inspect claims
conn = put_req_header(conn, "authorization", "Bearer #{jwt}")
{:ok, conn: conn, user: user}
end
test "and return user if token is valid", %{conn: conn, user: user} do
email = user.email
conn = get conn, current_user_path(conn, :current)
response = json_response(conn, 200)
IO.puts "---------- test response--------"
IO.inspect response
assert %{"email" => email} = response
end
end
我的控制器:
defmodule BikefitWeb.UserController do
use BikefitWeb, :controller
alias Bikefit.Riders
alias Bikefit.Riders.User
plug Guardian.Plug.EnsureAuthenticated, handler: BikefitWeb.AuthController
action_fallback BikefitWeb.FallbackController
def current(conn, _params) do
user = conn |> Guardian.Plug.current_resource
conn
|> render(BikefitWeb.UserView, "show.json-api", user: user)
end
end
我的看法是:
defmodule BikefitWeb.UserView do
use BikefitWeb, :view
alias BikefitWeb.UserView
def render("show.json-api", %{user: user}) do
%{data: render_one(user, UserView, "user.json")}
end
def render("user.json", %{user: user}) do
%{id: user.id,
email: user.email,
auth_provider: user.auth_provider}
end
end
我的路由器:
defmodule BikefitWeb.Router do
use BikefitWeb, :router
pipeline :api do
plug :accepts, ["json", "json-api"]
plug JaSerializer.Deserializer
end
pipeline :api_auth do
plug :accepts, ["json", "json-api"]
plug Guardian.Plug.Pipeline,
module: Bikefit.Guardian,
error_handler: BikefitWeb.AuthErrorHandler
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
plug Guardian.Plug.LoadResource
plug JaSerializer.Deserializer
end
scope "/api/v1", BikefitWeb do
pipe_through :api_auth
resources "/users", UserController, except: [:new, :edit]
get "/user/current", UserController, :current, as: :current_user
delete "/logout", UserController, :delete
end
end
测试的输出:
** (FunctionClauseError) no function clause matching in Plug.Conn.resp/3
The following arguments were given to Plug.Conn.resp/3:
# 1
%Plug.Conn{adapter: {Plug.Adapters.Test.Conn, :...},
assigns: %{layout: false, user: %Bikefit.Riders.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
auth_provider: "some auth_provider", email: "some email", id: 272, inserted_at: ~N[2018-02-24 06:28:20.876426],
password: nil, password_hash: nil, updated_at: ~N[2018-02-24 06:28:20.876442]}},
before_send: [#Function<1.42514850/1 in Plug.Logger.call/2>], body_params: %{},
cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "www.example.com", method: "GET", owner: #PID<0.418.0>,
params: %{}, path_info: ["api", "v1", "user", "current"], path_params: %{}, peer: {{127, 0, 0, 1}, 111317},
port: 80, private: %{BikefitWeb.Router => {[], %{}},
:guardian_default_claims => %{"aud" => "Bikefit", "exp" => 1522045700, "iat" => 1519453700, "iss" => "Bikefit", "jti" => "5f8312a9-8f49-4f0a-9654-968882cd3f90", "nbf" => 1519453699, "sub" => "some email", "typ" => "access"},
:guardian_default_resource => %Bikefit.Riders.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, auth_provider: "some auth_provider", email: "some email", id: 272, inserted_at: ~N[2018-02-24 06:28:20.876426], password: nil, password_hash: nil, updated_at: ~N[2018-02-24 06:28:20.876442]},
:guardian_default_token => "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJCaWtlZml0IiwiZXhwIjoxNTIyMDQ1NzAwLCJpYXQiOjE1MTk0NTM3MDAsImlzcyI6IkJpa2VmaXQiLCJqdGkiOiI1ZjgzMTJhOS04ZjQ5LTRmMGEtOTY1NC05Njg4ODJjZDNmOTAiLCJuYmYiOjE1MTk0NTM2OTksInN1YiI6InNvbWUgZW1hac3MifQ.gt7B7itXs8HFWEzFwQxa5LJaDzSKkF1b2C4BDxw28nP3Q4_cHDi-PexZQDh8BbjD363qFKK9p9jvoQqqe9yx8A", :guardian_error_handler => BikefitWeb.AuthErrorHandler,
:guardian_module => Bikefit.Guardian, :phoenix_action => :current,
:phoenix_controller => BikefitWeb.UserController, :phoenix_endpoint => BikefitWeb.Endpoint,
:phoenix_format => "json", :phoenix_layout => {BikefitWeb.LayoutView, :app}, :phoenix_pipelines => [:api_auth],
:phoenix_recycled => true, :phoenix_router => BikefitWeb.Router, :phoenix_template => "show.json-api",
:phoenix_view => BikefitWeb.UserView, :plug_session_fetch => #Function<1.45862765/1 in Plug.Session.fetch_session/1>,
:plug_skip_csrf_protection => true}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1},
req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"accept", "application/json"},
{"authorization", "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJCaWtlZml0IiwiZXhwIjoxNTIyMDQ1NzAwLCJpYXQiOjE1MTk0NTM3MDAsImlzcyI6IkJpa2VmaXQRmMGEtOTY1NC05Njg4ODJjZDNmOTAiLCJuYmYiOjE1MTk0NTM2OTksInN1YiI6InNvbWUgZW1haWwiLCJ0eXAiOiJhY2Nlc3MifQ.gt7B7itXs8HFWEzFwQxa5LJaDzSKkF1b2C4BDxw28nP3Q4_cHDi-PexZQDh8BbjD363qFKK9p9jvoQqqe9yx8A"}],
request_path: "/api/v1/user/current", resp_body: nil, resp_cookies: %{},
resp_headers: [{"content-type", "application/vnd.api+json; charset=utf-8"},
{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "44e2jir0js16jn0pe2pf8qgbksc9346s"}],
scheme: :http, script_name: [], secret_key_base: "UD4qdbi6YOBRbCrf",
state: :unset, status: nil}
# 2
200
# 3
%{data: %{auth_provider: "some auth_provider", email: "some email", id: 272}}
Attempted function clauses (showing 3 out of 3):
def resp(%Plug.Conn{state: state}, status, _body) when not(state === :set or (state === :set_chunked or (state === :set_file or state === :unset)))
def resp(%Plug.Conn{}, _status, nil)
def resp(%Plug.Conn{} = conn, status, body) when is_binary(body) or is_list(body)
code: conn = get conn, current_user_path(conn, :current)
stacktrace:
(plug) lib/plug/conn.ex:505: Plug.Conn.resp/3
(plug) lib/plug/conn.ex:495: Plug.Conn.send_resp/3
(bikefit) lib/bikefit_web/controllers/user_controller.ex:1: BikefitWeb.UserController.action/2
(bikefit) lib/bikefit_web/controllers/user_controller.ex:1: BikefitWeb.UserController.phoenix_controller_pipeline/2
(bikefit) lib/bikefit_web/endpoint.ex:1: BikefitWeb.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
(bikefit) lib/bikefit_web/endpoint.ex:1: BikefitWeb.Endpoint.plug_builder_call/2
(bikefit) lib/bikefit_web/endpoint.ex:1: BikefitWeb.Endpoint.call/2
(phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
test/bikefit_web/controllers/user_controller_test.exs:63: (test)
**(FunctionClauseError)Plug.Conn.resp/3中没有匹配的函数子句
为Plug.Conn.resp/3提供了以下参数:
# 1
%Plug.Conn{adapter:{Plug.Adapters.Test.Conn,:…},
分配:%{layout:false,用户:%Bikefit.Riders.user{{uuuuu meta}uuuuu:#exto.Schema.Metadata,
认证提供者:“一些认证提供者”,电子邮件:“一些电子邮件”,id:272,插入地址:~N[2018-02-24 06:28:20.876426],
密码:nil,密码\u散列:nil,更新地址:~N[2018-02-24 06:28:20.876442]},
在发送之前:[函数],体参数:%{},
cookies:%Plug.Conn.Unfetched{aspect::cookies},暂停:false,主机:“www.example.com”,方法:“GET”,所有者:#PID,
参数:%{},路径信息:[“api”,“v1”,“用户”,“当前”],路径参数:%{},对等:{127,0,0,1},111317},
端口:80,专用:%{BikefitWeb.Router=>{[],%{},
:guardian\u default\u claims=>%{“aud”=>“Bikefit”,“exp”=>1522045700,“iat”=>1519453700,“iss”=>“Bikefit”,“jti”=>“5f8312a9-8f49-4f0a-9654-968882cd3f90”,“nbf”=>1519453699,“sub”=>“一些电子邮件”,“典型”=>“访问”},
:guardian_default_resource=>%Bikefit.Riders.User{uuuuuu meta_uuu:#exto.Schema.Metadata,身份验证提供者:“一些身份验证提供者”,电子邮件:“一些电子邮件”,id:272,插入地址:~N[2018-02-24 06:28:20.876426],密码:nil,密码哈希:nil,更新地址:~N[2018-02-24 06:28:20.876442],
:监护人\默认\令牌=>“Eyjhbgcioijiuzuxmiiir5cci6IKPxvcj9.Eyjhdwqioijcawtlzml0iiiiijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj“,:guardian\u error\u handler=>BikefitWeb.AuthErrorHandler,
:guardian_module=>Bikefit.guardian,:phoenix_action=>:current,
:phoenix_controller=>BikefitWeb.UserController,:phoenix_endpoint=>BikefitWeb.endpoint,
:phoenix_format=>“json”,:phoenix_layout=>{BikefitWeb.LayoutView,:app},:phoenix_pipelines=>[:api_auth],
:phoenix_recycled=>true,:phoenix_router=>BikefitWeb.router,:phoenix_template=>“show.json api”,
:phoenix_view=>BikefitWeb.UserView,:plug_session_fetch=>,
:plug_skip_csrf_protection=>true},查询参数:%{},查询字符串:,远程ip:{127,0,0,1},
请求cookies:%Plug.Conn.Unfetched{aspect::cookies},请求头:[{“accept”,“application/json”},
{“授权”、“持票人”eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.EYJDWQOIJCAWTLZML0IIWIZHWIJOXNTIYMDQ1NZKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYK0MTKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYK,
请求路径:“/api/v1/user/current”,响应主体:nil,响应cookie:%{},
响应头:[{“content-type”,“application/vnd.api+json;charset=utf-8”},
{“缓存控制”,“最大年龄=0,私有,必须重新验证”},{“x-request-id”,“44e2jir0js16jn0pe2pf8qgbksc9346s”},
方案::http,脚本名称:[],密钥库:“UD4QDBI6YOBCRF”,
状态::未设置,状态:nil}
# 2
200
# 3
%{数据:%{auth_提供者:“某些auth_提供者”,电子邮件:“某些电子邮件”,id:272}
尝试的函数子句(显示3个中的3个):
def resp(%Plug.Conn{state:state},status,_body)不在时(state==:set或(state==:set_chunked或(state==:set_file或state==:unset)))
def响应(%Plug.Conn{},_状态,无)
def resp(%Plug.Conn{}=Conn,status,body)何时为二进制(body)或列表(body)
代码:conn=获取conn,当前用户路径(conn,:当前)
堆栈跟踪:
(plug)lib/plug/conn.ex:505:plug.conn.resp/3
(plug)lib/plug/conn.ex:495:plug.conn.send_resp/3
(bikefit)lib/bikefit\u web/controllers/user\u controller.ex:1:BikefitWeb.UserController.action/2
(bikefit)lib/bikefit\u web/controllers/user\u controller.ex:1:BikefitWeb.UserController.phoenix\u controller\u管道/2
(bikefit)lib/bikefit_web/endpoint.ex:1:BikefitWeb.endpoint.instrument/4
(凤凰城)lib/phoenix/router.ex:278:phoenix.router.\uuuuuu呼叫\uuuuu/1
(bikefit)lib/bikefit\u web/endpoint.ex:1:BikefitWeb.endpoint.plug\u builder\u call/2
(bikefit)lib/bikefit_web/endpoint.ex:1:BikefitWeb.endpoint.call/2
(phoenix)lib/phoenix/test/conn_test.ex:224:phoenix.connstest.dispatch/5
test/bikefit\u web/controllers/user\u controller\u test.exs:63:(测试)
我认为问题在于conn的
state::unset
导致函数子句匹配出现问题,但我不确定为什么会发生这种情况,因为我认为我的控制器和视图与教程匹配。有什么想法吗 您需要告诉Phoenix如何通过。默认情况下,它知道如何对.json
进行编码,但对.json api
一无所知,这就是为什么它们在默认情况下没有编码
将其重命名为.json或向格式编码器添加一个新条目就足以修复它。您需要告诉Phoenix如何通过。默认情况下,它知道如何对
.json
进行编码,但对.json api
一无所知,这就是为什么它们在默认情况下没有编码
重命名它.json或向格式编码器添加新条目就足以修复它。如果需要json响应,则应使用
json
notrender
:render(conn,BikefitWeb.UserView,“show.json api”,user:user)
⇒ json(conn,BikefitWeb.UserView,“show.json api”,user:user)
.json\4似乎不存在于Phoenix.Controller模块中。仅json\2,它不调用视图。菲尼克斯控制器测试指南