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

我正在尝试在我的身份validation系统中实现JWT,并且我有几个问题。 要存储令牌,我可以使用cookie,但也可以使用localStoragesessionStorage

哪个会是最好的select?

我读过JWT保护CSRF的网站。 但是,我无法想象如何将这个工作假设我保存在Cookie存储的JWT令牌。

那么它将如何保护CSRF?

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

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

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

 http://exmple.com?jwt=token 

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

更新2

我安装了高级REST客户端谷歌浏览器扩展,并能够将令牌作为自定义标题。 在向服务器发出GET请求时,是否可以通过Javascript设置这个标题数据?

看看这个网站: https : //auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

如果要存储它们,则应使用localStorage或sessionStorage(如果可用)或cookie。 您也应该使用授权标题,而不是基本的scheme,使用承载之一:

 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> 

select存储更多的是取舍,而不是试图find一个最终的最佳select。 我们来看几个选项:

选项1 – Web存储( localStoragesessionStorage

优点

  • 浏览器不会自动将Web存储中的任何内容包含到HTTP请求中,使其容易受到CSRF的攻击
  • 只能通过运行在与创build数据完全相同的域中的Javascript来访问
  • 允许使用最正确的方法在HTTP中传递令牌authentication凭证(拥有Bearerscheme的Authorization标头)
  • 樱桃挑选应包含authentication的请求是非常容易的

缺点

  • 不能通过在创build数据的子域中运行的Javascript访问(由example.com写入的值不能被sub.example.com读取)
  • Is️容易受到XSS的影响
  • 为了执行已authentication的请求,您只能使用浏览器/库API来允许您自定义请求(在Authorization标头中传递令牌)

用法

利用浏览器localStoragesessionStorage API存储并在执行请求时检索令牌。

 localStorage.setItem('token', 'asY-x34SfYPk'); // write console.log(localStorage.getItem('token')); // read 

选项2 – 仅HTTP cookie

优点

  • 容易受到XSS的影响
  • 浏览器自动将该令牌包含在满足cookie规范(域,path和生命周期)的任何请求中,
  • 该cookie可以在顶级域中创build,并用于由子域执行的请求

缺点

  • It️CSRF很脆弱
  • 您需要了解并始终考虑在子域中使用cookie的可能性
  • 樱桃采摘应该包括cookies的请求是可行的,但更混乱
  • 您可能(仍然)遇到一些浏览器如何处理cookie的问题
  • ⚠️如果您不小心,可以实施易受XSS影响的CSRF缓解策略
  • 服务器端需要validationcookie来进行身份validation,而不是更合适的Authorization标头

用法

你不需要做任何客户端的事情,因为浏览器会自动处理你的东西。

选项3 – 服务器端忽略 Javascript可访问的cookie

优点

  • 容易受到CSRF( 因为它被服务器忽略
  • 该cookie可以在顶级域中创build,并用于由子域执行的请求
  • 允许使用最正确的方法在HTTP中传递令牌authentication凭证(拥有Bearerscheme的Authorization标头)
  • 樱桃select应包含身份validation的请求是相当容易的

缺点

  • It️XSS容易受到攻击
  • 如果您不小心设置cookie的path,那么浏览器会自动将cookie包含在请求中,这会增加不必要的开销
  • 为了执行已authentication的请求,您只能使用浏览器/库API来允许您自定义请求(在Authorization标头中传递令牌)

用法

您利用浏览器document.cookie API存储并在执行请求时检索令牌。 这个API不像Web存储一样细致(你得到所有的cookies),所以你需要额外的工作来parsing你所需要的信息。

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

补充笔记

这看起来可能是一个奇怪的select,但它确实具有很好的优势,您可以将存储设备用于顶级域名,而所有子域名都是Web存储所不能提供的。 但是,实施起来比较复杂。


结论 – 最后的注释

对大多数常见场景的build议是select1 ,主要是因为:

  • 如果你创build一个Web应用程序,你需要处理XSS; 总是独立于你存储你的令牌的地方
  • 如果你不使用基于cookie的authentication,CSRF甚至不应该在你的雷达上popup,所以这是一个小问题

另外请注意,基于cookie的选项也完全不同,因为选项3 cookie纯粹用作存储机制,因此它几乎就像是客户端的实现细节。 然而,选项2意味着更传统的处理authentication的方式; 进一步阅读这个cookie与标记的东西,你可能会发现这篇文章有趣: 曲奇与令牌:权威指南 。

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

这个博客文章有优秀的浏览器存储与cookies比较,并在每种情况下处理每一个潜在的攻击。 https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

较短的答案/扰stream:cookies并在jwt中添加xsrf标记。 详细的解释在博客文章。