当前位置: 首页 > 知识库问答 >
问题:

在基于浏览器的应用程序中保存JWT的位置以及如何使用它

田瀚
2023-03-14

我试图在我的认证系统中实现JWT,我有几个问题。要存储令牌,我可以使用Cookie,但也可以使用localStoresession sionstore

哪一个是最好的选择?

我已经读到JWT保护网站不受CSRF的影响。但是,如果我将JWT令牌保存在cookie存储中,我无法想象这将如何工作。

那么它将如何防止CSRF?

更新1
我看到一些使用示例,如下所示:

curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"

当我从浏览器向服务器发出请求时,如何实现这一点?我还看到一些人在URL中实现了令牌:

http://exmple.com?jwt=token

如果我想通过AJAX发出请求,那么我可以设置一个头,比如jwt:[token],然后我可以从头中读取token。

更新2

我安装了高级REST客户端Google Chrome扩展,并能够将令牌作为自定义头传递。在向服务器发出GET请求时,是否可以通过Javascript设置此头数据

共有3个答案

濮翰学
2023-03-14

这篇博客文章对浏览器存储和cookie进行了很好的并排比较,并解决了每种情况下的每一种潜在攻击。https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

简短的回答/剧透:cookies和在jwt中添加xsrf令牌。详细解释在博客帖子中。

羊舌高明
2023-03-14

[编辑]这是一个公认的答案,但若昂·安杰洛的回答更为详细,应予以考虑。尽管有一点值得注意,但由于安全实践自2016年11月以来不断发展,因此应采用有利于方案1的方案2。

请浏览本网站:https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

如果要存储它们,应使用localStorage或sessionStorage(如果可用)或Cookie。您还应该使用授权头,但不使用基本方案,而是使用承载头:

curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"

使用JS,您可以使用以下代码:

<script type='text/javascript'>
// define vars
var url = 'https://...';

// ajax call
$.ajax({
    url: url,
    dataType : 'jsonp',
    beforeSend : function(xhr) {
      // set header if JWT is set
      if ($window.sessionStorage.token) {
          xhr.setRequestHeader("Authorization", "Bearer " +  $window.sessionStorage.token);
      }

    },
    error : function() {
      // error handler
    },
    success: function(data) {
        // success handler
    }
});
</script>
暴辰龙
2023-03-14

选择存储更多的是权衡取舍,而不是试图找到一个确定的最佳选择。让我们看几个选项:

  • 浏览器不会自动包含任何从Web存储到HTTP请求的内容,使其不容易受到CSRF的攻击
  • 只能由在创建数据的完全相同的域中运行的Javascript访问
  • 允许使用语义最正确的方法在HTTP中传递令牌身份验证凭据(带有承载方案的授权头)
  • 选择应该包含身份验证的请求非常容易
  • 在创建数据的子域中运行的Javascript无法访问(由example.com编写的值不能由sub.example.com读取)
  • ⚠️易受XSS攻击
  • 为了执行经过验证的请求,您只能使用允许您自定义请求的浏览器/库API(在授权头中传递令牌)

您可以利用浏览器localStoragesessionStorageAPI来存储令牌,然后在执行请求时检索令牌。

localStorage.setItem('token', 'asY-x34SfYPk'); // write
console.log(localStorage.getItem('token')); // read
  • 它不易受XSS攻击
  • ⚠️它容易受到CSRF的攻击
  • 您需要注意并始终考虑Cookie在子域中的可能用途
  • Cherry选择应该包括cookie的请求是可行的,但更混乱
  • 您可能(仍然)在浏览器处理cookie的方式上遇到一些差异很小的问题
  • ⚠️如果你不小心,你可能会实施一个容易受到XSS攻击的CSRF缓解策略
  • 服务器端需要验证用于身份验证的cookie,而不是更合适的Authoration标头

您不需要在客户端执行任何操作,因为浏览器会自动为您处理事情。

  • 它不易受到CSRF的攻击(因为它被服务器忽略)
  • cookie可以在顶级域中创建,并在子域执行的请求中使用
  • 允许使用语义最正确的方法在HTTP中传递令牌身份验证凭据(使用承载方案的授权头)
  • 选择应该包含身份验证的请求有些容易
  • ⚠️ 它易受XSS攻击
  • 如果不小心设置cookie的路径,浏览器会自动将cookie包含在请求中,这将增加不必要的开销
  • 为了执行经过身份验证的请求,您只能使用允许您自定义请求的浏览器/库API(在授权标题中传递令牌)

您可以利用浏览器文档。cookieAPI,用于在执行请求时存储并检索令牌。这个API不像Web存储那样细粒度(你得到了所有的cookie),所以你需要额外的工作来解析你需要的信息。

document.cookie = "token=asY-x34SfYPk"; // write
console.log(document.cookie); // read

这可能看起来是一个奇怪的选择,但它确实有一个很好的好处,你可以有一个顶级域名和所有子域可用的存储,这是网络存储不会给你的。然而,实现起来更复杂。

我对大多数常见情况的建议是采用备选方案1,主要是因为:

  • 如果你创建一个Web应用程序,你需要处理XSS;始终独立于代币的存储位置

还要注意的是,基于cookie的选项也有很大不同,因为选项3 cookie纯粹用作存储机制,所以它几乎就像是客户端的一个实现细节。然而,选项2意味着处理身份验证的更传统的方式;要进一步了解cookies vs Tokens,您可能会发现这篇文章很有趣:cookies vs Tokens:最终指南。

最后,没有一个选项提到它,但是使用HTTPS当然是强制性的,这意味着应该适当地创建cookie来考虑这一点。

 类似资料:
  • 问题内容: 我正在尝试在身份验证系统中实现JWT,但我有几个问题。要存储令牌,我可以使用Cookie,但也可以使用或。 哪个是最佳选择? 我读过,JWT保护站点免受CSRF的侵害。但是,假设我将JWT令牌保存在cookie存储中,我无法想象它将如何工作。 那么如何保护它免受CSRF的侵害? 更新1 我看到了一些用法示例,如下所示: 当我从浏览器向服务器发出请求时,该如何实现?我还看到有人在URL中

  • 我知道基于cookie的身份验证。可以应用SSL和HttpOnly标志来保护基于Cookie的身份验证免受MITM和XSS的攻击。然而,需要采取更多的特别措施,以保护它免受CSRF的影响。他们只是有点复杂。(参考) 最近,我发现JSON Web令牌(JWT)作为一种身份验证解决方案非常热门。我知道JWT的编码、解码和验证。但是,我不明白为什么有些网站/教程告诉如果使用JWT就不需要CSRF保护。我

  • 我第一次使用JSON Web令牌(JWT)。我正在制作一个节点。js应用程序。我想使用JWT进行身份验证。根据文档,我将JSON令牌返回到前端。 但是我不知道如何将这个JSON令牌保存到我的浏览器头中,这样它就不会丢失,并随头一起再次发送到后端。如何将它保存在我的浏览器存储中,并在每次向后端发送请求时将其添加到请求头中?

  • 所以目前我有一个托管在亚马逊S3上的反应应用程序,它是通过云前沿CDN提供的,但是,每次我发布新的产品版本,最终用户都必须深度刷新整个页面(因为上一个版本的内容仍然保留在浏览器缓存中)。有没有什么我只能在发布产品版本时使CDN缓存和浏览器缓存无效。顺便说一句,我使用GitLab ci。

  • 问题内容: 我们可以从javascript获取浏览器名称,但是有没有办法相应地更改css。我的意思是一些css文件类,因为我不想链接另一个css文件,我想在上面写样式 问题答案: 有两种方法: 客户端:您需要使用Javascript来检测浏览器并导入适当的CSS样式。看一下这篇文章。(链接不再可用) 服务器端:您需要检测]用户代理并提供适当的HTML。这是为此的PHP源链接。

  • 问题内容: 如何在基于Java的桌面应用程序中嵌入浏览器?我是否可以直接与嵌入式浏览器通信(而不是通过本地主机)……例如加载html文本,捕获onclick事件,获取表单值? 谢谢 问题答案: 查看Eclipse,它具有一个嵌入式浏览器,用户可以对其进行配置(它们支持多种浏览器)。 即使您通过AWT_SWT桥使用基于AWT的应用程序,也可能会嵌入他们的浏览器。 此文章可以帮助您开始。