JWT:当用户打开新标签时如何处理 GET 请求?
Posted
技术标签:
【中文标题】JWT:当用户打开新标签时如何处理 GET 请求?【英文标题】:JWT: how to handle GET requests when user opens a new tab? 【发布时间】:2015-07-15 16:17:54 【问题描述】:在以 API 为中心的应用程序上使用 JWT 而不是 Cookie 有很多优势,我知道您可以在通过浏览器访问应用程序时将令牌存储在 sessionStorage 中。 您可以在您的 JS 代码上设置一个拦截器,以便在 GET 请求的 Authorization 标头中注入 JWT 令牌——只要这些 GET 请求是从对用户进行身份验证的相同代码发出的。
但是当用户通过身份验证,然后打开一个新选项卡并尝试访问应用程序/网站的不同限制区域(甚至相同区域)时会发生什么?在这种情况下,没有拦截器可以在新选项卡上的 Authorization 标头上注入令牌。我想服务器会收到 GET 请求,在 Authorization 标头上查找 JWT 令牌并找不到它,拒绝请求。
当您使用 Cookie 时,它们总是由浏览器本地发送,您不必担心新标签和身份验证。
当用户在第一个选项卡中进行身份验证时,有没有办法在浏览器上为域全局设置授权标头?如果有的话,通常的解决方案是什么?
【问题讨论】:
【参考方案1】:在没有正确凭据(如 JWT)的情况下访问受保护的 URL 时,浏览器将被重定向到特定端点(例如在授权服务器上),在那里它可以获得新的 JWT。
这发生在例如 OpenID Connect Implicit 流中:http://openid.net/specs/openid-connect-implicit-1_0.html
但也可以将 JWT 存储在 cookie 中。这不是呈现 JWT 的标准化方式,因此它特定于您的客户端/浏览器和受保护的应用程序。
【讨论】:
我最终使用 cookie 来保存 JWT,但它是由客户端在第一次身份验证后使用 github.com/js-cookie/js-cookie 设置的。我的服务器代码按以下顺序检查请求中的 JWT:标头、正文、cookie。因此,任何时候用户打开一个新选项卡,都会使用本地设置的 cookie。其他页内请求在标头中注入 JWT。这样,操作是面向 API 的,在最后一种情况下回退到 cookie。 “这不是一种标准化的方式” 那么正确的方式是什么? 将其显示在授权标头“授权:承载由于新发现,我决定对此问题进行更新。我不会改变原来的答案。
首先,根据我对原始答案的cmets:
我最终使用 cookie 来保存 JWT,但它是由客户端设置的 首次认证后使用github.com/js-cookie/js-cookie。我的 服务器代码按以下顺序检查请求中的 JWT:标头, 身体,饼干。因此,每当用户打开一个新选项卡时,本地设置 使用 cookie。其他页内请求在标头中注入 JWT。 这样,操作是面向API的,回退到一个cookie 最后一种情况。
但是,我也担心浏览器上生成的 cookie 的安全性。这是因为,由于它是由客户端 javascript 生成的,因此您不能使用 HttpOnly,而是将其打开以供 XSS 使用。
解决方案
由于我使用的是 Sails,所以我决定在服务器上创建一个带有 JWT 令牌的 cookie,并将其与响应一起发送,响应中还包含主体上一个对象上的 JWT 令牌。
http://sailsjs.com/documentation/reference/response-res/res-cookie
res.cookie()
设置一个带有名称(名称)和值(值)的 cookie 一起发送 回应。
res.cookie('x-access-token', token,
expires: expire,
httpOnly: true
);
return res.status(200).json(
"x-access-token" : token
);
此 cookie 不需要在服务器上启用会话,因此它实现了使用 JWT 的“无会话”优势。
如果客户端是浏览器,它将在后续请求中存储和重用令牌,包括借助 HttpOnly cookie 在新选项卡上。
如果是其他类型的客户端,它的响应体上有 JWT 令牌。
【讨论】:
我相信这不仅限于 Sails。听起来res.cookie()
只是在响应中设置了Set-Cookie
标头:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie。无论如何,这听起来对我来说是正确的技术。以上是关于JWT:当用户打开新标签时如何处理 GET 请求?的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中验证 JWT 时如何处理 InvalidSignatureException?