zer*_*ing 41 javascript security cookies web-services jwt
我正在尝试在我的身份验证系统中实现JWT,我有几个问题.要存储令牌,我可以使用cookie,但也可以使用localStorage或sessionStorage.
哪个是最好的选择?
我已经读过JWT保护网站免受CSRF的侵害.但是,我无法想象假设我将JWT令牌保存在cookie存储中会如何工作.
那么它将如何保护CSRF?
更新1
我看到了一些使用示例,如下所示:
curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"
Run Code Online (Sandbox Code Playgroud)
当我从浏览器向服务器发出请求时,如何实现?我还看到有些人在URL中实现了令牌:
http://exmple.com?jwt=token
Run Code Online (Sandbox Code Playgroud)
如果我通过AJAX发出请求,那么我可以设置一个标题jwt: [token],然后我可以从标题中读取标记.
更新2
我安装了高级REST客户端谷歌浏览器扩展,并能够将令牌作为自定义标头传递.在向服务器发出GET请求时,是否可以通过Javascript设置此标头数据?
Joã*_*elo 87
选择存储更多的是权衡,而不是试图找到明确的最佳选择.我们来看几个选项:
localStorage或sessionStorage)Authorization带有Bearer方案的标头)example.com无法读取sub.example.com)Authorization标头中传递令牌)您可以利用浏览器localStorage或sessionStorageAPI在执行请求时存储然后检索令牌.
localStorage.setItem('token', 'asY-x34SfYPk'); // write
console.log(localStorage.getItem('token')); // read
Run Code Online (Sandbox Code Playgroud)
Authorization标头您无需在客户端执行任何操作,因为浏览器会自动为您处理任何事情.
Authorization带有Bearer方案的标头)Authorization标头中传递令牌)您可以利用浏览器document.cookieAPI在执行请求时存储然后检索令牌.此API不像Web存储那样精细(您获得所有cookie),因此您需要额外的工作来解析所需的信息.
document.cookie = "token=asY-x34SfYPk"; // write
console.log(document.cookie); // read
Run Code Online (Sandbox Code Playgroud)
这似乎是一个奇怪的选择,但它确实有一个很好的好处,你可以让存储可用于顶级域和所有子域,这是Web存储不会给你的东西.但是,实施起来更复杂.
我对大多数常见情况的建议是选择1,主要是因为:
另请注意,基于cookie的选项也大不相同,因为选项3 cookie仅用作存储机制,因此它几乎就像是客户端的实现细节.但是,备选方案2意味着更传统的处理身份验证的方式; 为了进一步阅读这个cookie vs令牌,你可能会发现这篇文章很有趣:Cookies vs Tokens:The Definitive Guide.
最后,没有一个选项提到它,但当然必须使用HTTPS,这意味着应该适当地创建cookie以考虑到这一点.
Flo*_*lli 22
请访问以下网站:https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
如果要存储它们,则应使用localStorage或sessionStorage(如果可用)或cookie.您还应该使用Authorization标头,但不使用Basic方案,而是使用Bearer one:
curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"
Run Code Online (Sandbox Code Playgroud)
使用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>
Run Code Online (Sandbox Code Playgroud)
小智 11
此博客文章对浏览器存储与Cookie进行了良好的并排比较,并解决了每种情况下的每次潜在攻击.https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
较短的答案/扰流板:cookie并在jwt中添加xsrf令牌.博客文章中的详细说明.
你永远不应该将JWT 存储在内存之外。
如果您想在长时间会话期间保留 JWT(例如,令牌仅过期 15 分钟,则为 1 小时),请在令牌即将过期时在后台以静默方式再次登录用户。
如果您想跨会话持久保存 JWT,则应使用刷新令牌。顺便说一句,其中大部分时间也用于上述目的。您应该将其存储在 HttpOnly cookie 中(更准确地说,服务器设置是通过 Set-Cookie 标头进行设置,前端调用 /refresh_token API 端点。)
顺便说一句,刷新令牌是最不有害的。作为补充,您应该确保遵循缓解 XSS 的最佳实践。
localStorage、sessionStorage 和 cookie 都有其漏洞。
这是我读过的关于 JWT 的最佳指南: https: //blog.hasura.io/best-practices-of-using-jwt-with-graphql/
截至2021和事物发展有点引进的的SameSite:国际机场/严格的选项饼干上最nowdays浏览器
因此,要详细说明 João Angelo 的答案,我想说现在最安全的方法是:
使用以下选项将JWT存储在 cookie 中
这将同时避免 XSS 和 CSRF