JWT:用户打开新标签页时如何处理 GET 请求?
JWT: how to handle GET requests when user opens a new tab?
在 API-centric 应用程序上使用 JWT 而不是 Cookies 有很多优势,我知道您可以在通过浏览器访问应用程序时将令牌存储在 sessionStorage 上。
您可以在 JS 代码上设置一个拦截器,以便在 GET 请求的授权 header 上注入 JWT 令牌——只要这些 GET 请求是从对用户进行身份验证的相同代码发出的。
但是当用户通过身份验证后会发生什么,然后打开一个新选项卡并尝试访问 app/site 的不同限制区域(甚至相同区域)?在这种情况下,没有拦截器在新选项卡上的 Authorization header 上注入令牌。我想服务器会收到 GET 请求,在授权 header 上寻找 JWT 令牌,但找不到它,拒绝请求。
当您使用 Cookie 时,它们始终由浏览器本机发送,您不必担心新标签和身份验证。
有没有办法在用户在第一个选项卡中进行身份验证时在浏览器上为域全局设置授权 header?如果有的话,一般的解决方法是什么?
在没有正确凭据(如 JWT)的情况下访问受保护的 URL 时,浏览器将被重定向到特定端点(例如在授权服务器上),在那里它可以获得新的 JWT。
例如在 OpenID Connect 隐式流程中会发生这种情况:http://openid.net/specs/openid-connect-implicit-1_0.html
但也可以将 JWT 存储在 cookie 中。这不是呈现 JWT 的标准化方式,因此它将特定于您的 client/browser 和受保护的应用程序。
由于有新发现,我决定更新此问题。我不会改变原来的答案。
首先,根据我对原答案的评论:
I ended up using a cookie to hold the JWT, but it is set by the client
using github.com/js-cookie/js-cookie after first authentication. My
server code checks for the JWT in the request in this order: header,
body, cookie. So any time the user opens a new tab, the local-set
cookie is used. Other in-page requests inject the JWT in a header.
This way, the operation is API-oriented, falling back to a cookie in
last case.
但是,我也担心在浏览器上生成的 cookie 的安全性。这是因为,由于它是由客户端生成的 JavaScript,您不能使用 HttpOnly,使其对 XSS 开放。
解决方案
由于我使用的是 Sails,所以我决定在服务器上使用 JWT 令牌创建一个 cookie,并将其与响应一起发送,该响应还包含正文对象上的 JWT 令牌。
http://sailsjs.com/documentation/reference/response-res/res-cookie
res.cookie()
Sets a cookie with name (name) and value (value) to be sent along with
the response.
res.cookie('x-access-token', token, {
expires: expire,
httpOnly: true
});
return res.status(200).json({
"x-access-token" : token
});
此 cookie 不需要在服务器上启用会话,因此它实现了使用 JWT 的 "sessionless" 优势。
如果客户端是浏览器,它将在后续请求中存储和重用令牌,包括借助 HttpOnly cookie 在新选项卡上。
如果是其他类型的客户端,它在响应主体上有 JWT 令牌。
在 API-centric 应用程序上使用 JWT 而不是 Cookies 有很多优势,我知道您可以在通过浏览器访问应用程序时将令牌存储在 sessionStorage 上。 您可以在 JS 代码上设置一个拦截器,以便在 GET 请求的授权 header 上注入 JWT 令牌——只要这些 GET 请求是从对用户进行身份验证的相同代码发出的。
但是当用户通过身份验证后会发生什么,然后打开一个新选项卡并尝试访问 app/site 的不同限制区域(甚至相同区域)?在这种情况下,没有拦截器在新选项卡上的 Authorization header 上注入令牌。我想服务器会收到 GET 请求,在授权 header 上寻找 JWT 令牌,但找不到它,拒绝请求。
当您使用 Cookie 时,它们始终由浏览器本机发送,您不必担心新标签和身份验证。
有没有办法在用户在第一个选项卡中进行身份验证时在浏览器上为域全局设置授权 header?如果有的话,一般的解决方法是什么?
在没有正确凭据(如 JWT)的情况下访问受保护的 URL 时,浏览器将被重定向到特定端点(例如在授权服务器上),在那里它可以获得新的 JWT。
例如在 OpenID Connect 隐式流程中会发生这种情况:http://openid.net/specs/openid-connect-implicit-1_0.html
但也可以将 JWT 存储在 cookie 中。这不是呈现 JWT 的标准化方式,因此它将特定于您的 client/browser 和受保护的应用程序。
由于有新发现,我决定更新此问题。我不会改变原来的答案。
首先,根据我对原答案的评论:
I ended up using a cookie to hold the JWT, but it is set by the client using github.com/js-cookie/js-cookie after first authentication. My server code checks for the JWT in the request in this order: header, body, cookie. So any time the user opens a new tab, the local-set cookie is used. Other in-page requests inject the JWT in a header. This way, the operation is API-oriented, falling back to a cookie in last case.
但是,我也担心在浏览器上生成的 cookie 的安全性。这是因为,由于它是由客户端生成的 JavaScript,您不能使用 HttpOnly,使其对 XSS 开放。
解决方案
由于我使用的是 Sails,所以我决定在服务器上使用 JWT 令牌创建一个 cookie,并将其与响应一起发送,该响应还包含正文对象上的 JWT 令牌。
http://sailsjs.com/documentation/reference/response-res/res-cookie
res.cookie()
Sets a cookie with name (name) and value (value) to be sent along with the response.
res.cookie('x-access-token', token, {
expires: expire,
httpOnly: true
});
return res.status(200).json({
"x-access-token" : token
});
此 cookie 不需要在服务器上启用会话,因此它实现了使用 JWT 的 "sessionless" 优势。
如果客户端是浏览器,它将在后续请求中存储和重用令牌,包括借助 HttpOnly cookie 在新选项卡上。
如果是其他类型的客户端,它在响应主体上有 JWT 令牌。