将Guardian令牌放入cookie中并从那里读取它们

时间:2017-03-14 21:10:09

标签: elixir phoenix-framework

我有一个使用Guardian进行JWT身份验证的应用程序。当用户登录时,响应包含正文中的jwt。然后,前端(即SPA)将jwt存储在localStorage中,并将其附加到从那里发送的每个请求的Authorization标头。然后,服务器使用Guardian的内置验证插件验证这一点:

pipeline :api do
  plug :accepts, ["json"]
  plug Guardian.Plug.VerifyHeader, realm: "Bearer"
end

我想改变它,以便将服务器作为安全cookie(Secure和{{1}发送到前端,而不是将JWT存储在localStorage(不安全)中。设置)。然后我希望Guardian从cookie中读取jwt,而不是从HttpOnly标题中读取。

Guardian是否支持此功能?

这是我的SessionController Authorization函数:

create

3 个答案:

答案 0 :(得分:0)

只需使用加密的会话cookie。 JWT令牌不打算存储在本地(在localStorage或cookie中),因为你只是放弃了JWT的用途。

在您的代码段中,您似乎使用JWT令牌替代会话Cookie。为什么不直接使用会话cookie?

答案 1 :(得分:0)

我认为您误解了JWT的工作原理。它是否暴露无关紧要。登录时获取JWT,然后在页面上重新加载/刷新。它在后端签名。整个要点就是能够拥有一个可以在FE中传递的对象,而不必暴露您的SKs

答案 2 :(得分:0)

更新:这是与Guardian 1.0一起使用的(如果可以的话,应该使用!)。

我认为您可以执行以下操作:

defmodule MyApp.SessionController do
  def login(conn, params) do
    # your code to find the user based on auth strategy here
    {:ok, jwt, _} = MyApp.Guardian.encode_and_sign(user)
    conn = put_session(conn, :auth_token, jwt)
    # send your response...
  end
end

将在Cookie上使用HttpOnlySecure标志。这样存储客户端应该没问题。

要获取用户,您可能需要编写自己的小插头,但是您的MyApp.Guardian模块可能看起来像这样:

defmodule MyApp.Guardian do
  use Guardian, otp_app: :my_app
  alias MyApp.Accounts

  def subject_for_token(%Accounts.Human{} = human, _claims) do
    {:ok, to_string(human.id)}
  end
  def subject_for_token(_, _) do
    {:error, :resource_not_found}
  end

  def resource_from_claims(%{"sub" => sub}) do
    case Accounts.find_human(sub) do
      nil -> {:error, :resource_not_found}
      human -> {:ok, human}
    end
  end
  def resource_from_claims(_) do
    {:error, :resource_not_found}
  end
end