【发布时间】:2017-05-03 22:50:25
【问题描述】:
在我的 Phoenix 应用程序中,我使用 Guardian 和 GuardianDb 进行用户授权。最初,我只使用 Guardian 并且所有带有身份验证过程的东西都工作得很好。但是,在将 GuardianDb 添加到组合中(用于令牌存储)之后,令牌记录正在正确创建,但是我收到了一个 no case clause matching 错误,这让工作很紧张,我似乎无法弄清楚如何解决它.一切都是这样的……
首先,来自mix.exs:
{:guardian, "~> 0.14"},
{:guardian_db, "~> 0.8.0"},
并且,如文档中所述,config.exs:
config :guardian, Guardian,
hooks: GuardianDb,
issuer: "MyApp",
ttl: {30, :days},
verify_issuer: true,
serializer: MyApp.GuardianSerializer
config :guardian_db, GuardianDb,
repo: MyApp.Repo,
schema_name: "guardian_tokens"
在session_controller.ex 中的create 操作期间引发错误:
def create(conn, %{"person" => person_params}) do
case authenticate(person_params) do
{:ok, person} ->
new_conn = Guardian.Plug.api_sign_in(conn, person, :access)
jwt = Guardian.Plug.current_token(new_conn)
json new_conn, %{status: "ok", data: person, meta: %{token: jwt}}
:error ->
json(conn |> put_status(401), %{status: "error", message: "Invalid credentials"})
end
end
当我尝试调用此操作时,在数据库中创建了所需的记录 - 但是,我收到以下错误(为整洁的格式添加了反斜杠):
(CaseClauseError) no case clause matching:
{:ok, {%MyApp.Person{__meta__: #Ecto.Schema.Metadata<:loaded, "people">, \
deleted_at: nil, email: "user@test.com", first_name: "FirstName", \
id: "people:Jz3bIt54283NvZb", inserted_at: ~N[2017-05-01 18:02:17.750603], \
last_name: "LastName", password: nil, updated_at: ~N[2017-05-01 18:02:17.750612]}, \
:access, %{"aud" => "people:Jz3bIt54283NvZb", "exp" => 1496441175, \
"iat" => 1493849175, "iss" => "MyApp", \
"jti" => "248e62ed-a2a2-4a0a-9e08-eae0190516c6", "pem" => %{}, \
"sub" => "Person:people:Jz3bIt54283NvZb", "typ" => "access"}, \
"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJQZXJzb246cGVvcGxlOkp6M2JJdEpnTzU4M052WmIiLCJleHAiOjE0OTY0NDExNzUsImlhdCI6MTQ5Mzg0OTE3NSwiaXNzIjoiUGhvZW5peEJhY2tlbmQiLCJqdGkiOiIyNDhlNjJkZC1hMmEyLTRhMGEtOWYwOC1lYWUwMTkwNTE2YzYiLCJwZW0iOnt9LCJzdWIiOiJQZXJzb246cGVvcGxlOkp6M2JJdEpnTzU4M052WmIiLCJ0eXAiOiJhY2Nlc3MifQ.DliX044wFmKpCrawuH3W_DoCya2VYAdrxZfwWEGWtW_ymDxXmQgV6XL3bHRkPKhSHziaFQFMvHIGS9yKtBfTkg"}}
有迹可循:
lib/guardian.ex:100: Guardian.encode_from_hooked/1
lib/guardian/plug.ex:178: Guardian.Plug.api_sign_in/4
(phoenix_backend) web/controllers/session_controller.ex:9: MyApp.SessionController.create/2
该跟踪的前两行来自依赖项,第三行引用来自上述控制器的Guardian.Plug.api_sign_in(conn, person, :access)。
现在,在我添加 GuardianDb 之前,此控制器操作运行良好,但现在该进程似乎挂在依赖项中的一个挂钩中,我不知道如何继续。
作为参考,跟踪中的第一行指向函数encode_from_hooked中的call_after_encode_and_sign_hook:
defp encode_from_hooked({:ok, {resource, type, claims_from_hook}}) do
{:ok, jwt} = encode_claims(claims_from_hook)
case call_after_encode_and_sign_hook( # THIS IS LINE 100
resource,
type,
claims_from_hook, jwt
) do
:ok -> {:ok, jwt, claims_from_hook}
{:error, reason} -> {:error, reason}
end
end
跟踪中的第二行指向api_sign_in函数中的encode_and_sign:
def api_sign_in(conn, object, type, new_claims) do
the_key = Map.get(new_claims, :key, :default)
new_claims = Map.delete(new_claims, :key)
case Guardian.encode_and_sign(object, type, new_claims) do # THIS IS LINE 178
{:ok, jwt, full_claims} ->
conn
|> set_current_resource(object, the_key)
|> set_claims({:ok, full_claims}, the_key)
|> set_current_token(jwt, the_key)
|> Guardian.hooks_module.after_sign_in(the_key)
{:error, reason} ->
set_claims(conn, {:error, reason}, the_key)
end
end
再次,我只想强调,控制器操作在合并 GuardianDb 之前运行良好。现在我添加了 GuardianDb,记录已在数据库中正确创建,但 new_conn 未正确定义。
我知道这里有很多代码,但我很难过 - 如果有人能提供一些启示,muy bueno。
【问题讨论】:
-
我没有使用过这些库,但是库本身内部的代码中断听起来像是一个错误。我会向错误跟踪器提交一张票。
-
酷,感谢您的想法。我会这样做,只是不确定我是否没有正确处理函数调用......