在我的凤凰应用中,我使用Guardian和GuardianDb进行用户授权。最初,我只使用Guardian,并且使用auth进程的一切工作都很好。然而,在将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"
create
中的session_controller.ex
操作期间出现错误:
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之前,这个控制器动作工作得很好,但现在看来这个进程在依赖项中的一个钩子中被挂起,我不知道如何继续。
作为参考,跟踪中的第一行指向函数call_after_encode_and_sign_hook
中的encode_from_hooked
:
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
并且跟踪中的第二行指向encode_and_sign
函数中的api_sign_in
:
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。
答案 0 :(得分:0)
好吧我确实找到了一个解决方案,虽然我不愿意在我的应用程序中实现它,因为这是在一个dep ...
我所要做的就是调整:ok
中的case
encode_from_hooked
子句,以便函数读取如下:
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(
resource,
type,
claims_from_hook, jwt
) do
{:ok, _} -> {:ok, jwt, claims_from_hook}
:ok -> {:ok, jwt, claims_from_hook}
{:error, reason} -> {:error, reason}
end
end
在使用:ok
返回元组时,只需要一个额外的案例。