【发布时间】:2017-08-05 09:57:58
【问题描述】:
我有一个使用 Guardian 的 JWT 身份验证的应用程序。当用户登录时,响应在正文中包含 jwt。然后前端(它是一个 SPA)将该 jwt 存储在 localStorage 中,并将其附加到从那里发送的每个请求的 Authorization 标头。然后服务器使用 Guardian 的内置验证插件对此进行验证:
pipeline :api do
plug :accepts, ["json"]
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
end
我想更改此设置,以便服务器不将 JWT 存储在 localStorage 中(这不安全),而是将它们作为安全 cookie 发送到前端(使用 Secure 和 HttpOnly 设置) .然后我希望 Guardian 从 cookie 中读取 jwt,而不是从 Authorization 标头中读取。
Guardian 是否支持此功能?
这是我的 SessionController create 函数:
def create(conn, params) do
case authenticate(params) do
{:ok, user} ->
new_conn = Guardian.Plug.api_sign_in(conn, user, :access)
jwt = Guardian.Plug.current_token(new_conn)
new_conn
|> put_status(:created)
|> render("show.json", user: user, jwt: jwt)
:error ->
conn
|> put_status(:unauthorized)
|> render("error.json")
end
end
【问题讨论】:
-
一个 JWT 是按定义签名的。为什么本地存储不如 cookie 存储安全??
-
因为
localStorage可以用 JavaScript 读取。这意味着如果将恶意 JavaScript 注入页面(例如在 XSS 攻击中),jwt 可能会被窃取并用于访问应用程序。相比之下,HttpOnlycookie 只能由浏览器访问。 -
并且cookies受CSRF约束,本地存储不受。你在抢劫彼得来付钱给保罗。
-
请阅读我上面提供的链接。具体来说,第 6 个要点。 “不要将会话标识符存储在本地存储中,因为 JavaScript 始终可以访问数据。Cookie 可以使用 httpOnly 标志降低这种风险。”