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。 “这不是一种标准化的方式” 那么正确的方式是什么? 将其显示在授权标头“授权:承载 @noderman 这种方法对您有何帮助?你有没有找到其他方法来做到这一点?我也有同样的情况,这是我能找出在新窗口上检查经过身份验证的用户的唯一方法。 这对我来说很好用。还要检查一下:stormpath.com/blog/…——为了安全起见,他们建议存储在 HttpOnly cookie 上,所以我不确定 js-cookie 是否会成为问题。但这是在页面上进行身份验证并能够在身份验证模式下打开另一个选项卡的唯一方法。【参考方案2】:

由于新发现,我决定对此问题进行更新。我不会改变原来的答案。

首先,根据我对原始答案的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 请求?的主要内容,如果未能解决你的问题,请参考以下文章

当 UI 允许新对象时如何处理取消

需要 iCloud 时如何处理首次启动体验?

在 Spring Boot 中验证 JWT 时如何处理 InvalidSignatureException?

使用app.get调用错误端点时如何处理?

用户关闭应用程序时如何处理用户在 Xamarin iOS 上单击本地通知?

当应用程序不在后台运行时如何处理推送通知