在基于浏览器的应用程序中如何保存JWT以及如何使用它
我正在尝试在我的身份validation系统中实现JWT,并且我有几个问题。 要存储令牌,我可以使用cookie,但也可以使用localStorage
或sessionStorage
。
哪个会是最好的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存储( localStorage
或sessionStorage
)
优点
- 浏览器不会自动将Web存储中的任何内容包含到HTTP请求中,使其不容易受到CSRF的攻击
- 只能通过运行在与创build数据完全相同的域中的Javascript来访问
- 允许使用最正确的方法在HTTP中传递令牌authentication凭证(拥有
Bearer
scheme的Authorization
标头) - 樱桃挑选应包含authentication的请求是非常容易的
缺点
- 不能通过在创build数据的子域中运行的Javascript访问(由
example.com
写入的值不能被sub.example.com
读取) - Is️容易受到XSS的影响
- 为了执行已authentication的请求,您只能使用浏览器/库API来允许您自定义请求(在
Authorization
标头中传递令牌)
用法
利用浏览器localStorage
或sessionStorage
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凭证(拥有
Bearer
scheme的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标记。 详细的解释在博客文章。