【问题标题】:Authenticate JWT with Guardian 1 and Phoenix 1.3使用 Guardian 1 和 Phoenix 1.3 对 JWT 进行身份验证
【发布时间】:2018-04-26 15:47:52
【问题描述】:

我做了一个项目,可以在这里找到:

https://github.com/rootkc/phx_auth_api

当我尝试发帖时:

http://0.0.0.0:4000/api/login

与身体:

{ "user": { "username": "kenneth", "password": "kenneth" } }

这是数据库中的用户。 我得到了回应:

{
"data": {
    "token": "eyJhbGciOiJIUzUxM[...]gbPVHTsSvrCA"
}

}

然后当我将该标记放在标题中时: Àuthorization: :token 有 Guardian 管道插头的电话 http://0.0.0.0:4000/api/users 我收到消息:未经身份验证

我不知道,我做错了什么。这是我第一个真正的 Phoenix 项目,我尝试遵循各种指南,但 {:guardian, "~> 1.0-beta"} 似乎很新,文档很糟糕。

【问题讨论】:

  • 既然有一个未解决的问题,我想我不会责怪任何人:github.com/ueberauth/guardian/issues/386.
  • 我为这个主题写了一个教程(PHX 1.3,Guardian 1):medium.com/@tylerpachal/…
  • 我确实看了很多你的文章 - 但那不是为了 API 身份验证。但我明白了!
  • 是否对 API 请求进行身份验证应该没有任何区别。一切都通过管道进入,并且可以在该管道上具有规则。很高兴你让它工作了。

标签: elixir phoenix-framework guardian


【解决方案1】:

信不信由你,Guardian 是一个文档齐全的库,它在 Elixir 和 Phoenix 项目中非常受欢迎。

请查看this article 进行简单的 API 身份验证。

您究竟想如何放置header?您应该使用 Guardian 已经定义的函数。

Guardian.encode_and_sign 返回您 {:ok, token, map} 并且您需要将此令牌传递给标头。 然后,监护人使用插件VerifyHeader 期望令牌在表单中

Authorization: token

如何混合使用监护功能完全取决于您,但上面的文章是非常好的介绍。

编辑 假设您正在运行Elixir 1.5.x,您可以尝试在 IEx 中运行您的服务器,然后调试正在发生的事情:iex -S mix phx.server。只需使用break! controller_name.action_name 并尝试在网络浏览器/邮递员等中单击此操作。

您也可以通过这种方式调试 Guardian 功能。

编辑 2

PhxAuthApi.Auth.Guardian 中,您不会在任何地方对令牌进行编码,但在 PhxAuthApi.Auth.Pipeline 中,您会要求,例如它有特定的声明,但您没有提供它们。

您通过创建无法正常工作的自定义模块过度设计了此身份验证。

【讨论】:

  • 我尝试按照卫报页面上一个开放的 github 问题中提供的这个示例 github.com/oskar1233/texts/blob/master/Guardian1.0/Guardian.md。但是我使用 SessionController 中的 encode_and_sign 对令牌进行编码。当我尝试使用jwt.io 解码 JWT 时,它具有有效负载“typ”=>“access”。所以我想当我在标题中使用 Authorization: token 调用管道时。我想这应该可行..
  • 你链接的文章是 2015 年的,卫报是不是从那时起变化很大?
  • 你链接的一些东西来自 0.14 并且 OP 专门要求 Guardian 1.0
【解决方案2】:

你的管道中有这个:

plug Guardian.Plug.VerifyHeader, claims: %{"typ" => "access"}, realm: :none

这意味着您的标题需要:

Authorization: none: <token>

因为这就是 Guardian.Plug.VerifyHeader 中的内容:

def init(opts \\ %{}) do
  opts_map = Enum.into(opts, %{})
  realm = Map.get(opts_map, :realm)
  if realm do
    {:ok, reg} = Regex.compile("#{realm}\:?\s+(.*)$", "i")
    Map.put(opts_map, :realm_reg, reg)
  else
    opts_map
  end
end

我猜您需要删除 realm: :none 设置,以便正确解析您的令牌。

【讨论】:

    【解决方案3】:

    我的Pipeline 中有错字。现在一切正常。

    【讨论】:

    • 这应该是一条评论。
    猜你喜欢
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2019-08-18
    • 2016-04-07
    • 2021-05-17
    • 2018-07-03
    • 1970-01-01
    相关资源
    最近更新 更多