【问题标题】:How do I store JWT and send them with every request using react如何存储 JWT 并使用 react 在每个请求中发送它们
【发布时间】:2017-01-03 17:06:57
【问题描述】:

很高兴知道,因为我的基本注册/身份验证系统正在运行。

所以基本上我明白了:

app.post('/login', function(req,res) {
 Users.findOne({
email: req.body.email
}, function(err, user) {
if(err) throw err;

if(!user) {
  res.send({success: false, message: 'Authentication Failed, User not found.'});
} else {
  //Check passwords
  checkingPassword(req.body.password, user.password, function(err, isMatch) {
    if(isMatch && !err) {
      //Create token
      var token = jwt.sign(user,db.secret, {
        expiresIn: 1008000
      });
      res.json({success: true, jwtToken: "JWT "+token});
    } else {
      res.json({success: false, message: 'Authentication failed, wrong password buddy'});

       }
     });
    }
 });
});

然后,每当我发送带有标头中 jwt 的 get 请求时,我都会使用 POSTMAN 保护我的 /admin 路由,一切正常。

现在这是棘手的部分,基本上当我要登录时,如果成功,然后将我重定向到管理页面,每次我尝试访问 admin/* 路由时,我想将我的 jwToken 发送到服务器但是问题是,我该如何实现?我没有使用 redux/flux,只是使用 react/react-router。

我不知道机制是如何工作的。

谢谢大家

【问题讨论】:

  • 如果您将令牌存储在本地存储中,这应该就是您所需要的。与任何应用程序相同,而不仅仅是反应
  • 哇,感谢您的快速回答。我怎样才能做到这一点?并且通过 localstorage 它是内置的 express 所以我可以调用这个方法..?
  • 本地存储是浏览器的东西。当您将令牌从 express 发送到您的客户端时,只需执行 localStorage.token = token 即可保存令牌 inlo 存储。然后,当您向服务器发出后续请求时,发送从本地存储中保存的令牌。反应路由器文档有一个正是这个github.com/reactjs/react-router/tree/master/examples/auth-flow的例子

标签: express reactjs passport.js react-router jwt


【解决方案1】:

不要将令牌存储在 localStorage 中,使用 xss 攻击可能会破坏令牌。 我认为最好的解决方案是在登录操作时向客户端提供访问令牌和刷新令牌。 将访问令牌保存在内存中(例如 redux 状态),并且应该在服务器上使用 httpOnly 标志创建刷新令牌(如果可能,还要使用安全标志)。 访问令牌应设置为每 2-3 分钟过期一次。 为了确保用户不必每 2-3 分钟输入一次凭据,我设置了一个间隔,在当前令牌过期之前调用 /refreshToken 端点(静默刷新令牌)。

这样,访问令牌就不会被 xss/csrf 破坏。 但是使用 xss 攻击,攻击者可以代表您调用 /refreshToken 端点,但这不会有害,因为返回的令牌不会被破坏。

【讨论】:

  • 您能否详细说明为什么对/refreshtoken 端点的 xss/csrf 攻击不会有害。如果他们进行此调用,他们不会获得访问令牌。
  • 访问令牌存储在内存中,而不是cookie或本地存储中,因此csrf无法利用任何cookie或现有会话,xss攻击的唯一方法是攻击者将知道你在内存中存储令牌的确切位置,足够聪明,不要轻易破坏它,你会没事的。
  • 现在我正在使用另一种不那么痛苦但足够安全的解决方案。在服务器端,我将 jwt 分成两部分。一个带有有效负载和标头,另一个带有签名。我将第一部分存储在具有相同站点标志的 cookie 中,第二部分存储在 httpOnly cookie 中也具有相同站点。当服务器收到请求时,它会同时获取 cookie 并重新组装 jwt,然后检查其验证。我还将另一个用户标识符(如用户 ID)作为请求标头发送,并且此用户 ID 也在 jwt 签名中加密,因此它是另一个保护层 mak
  • 如果访问令牌在内存中,你如何处理浏览器刷新?当您仍在等待刷新令牌时,用户不会看到一瞬间的登录页面
【解决方案2】:

1-登录组件向API服务器端点发送登录请求

2- 服务器 API 端点返回一个令牌

3- 我将令牌保存在用户的本地存储中

4- 从现在开始,所有 API 调用都将包含在标头中

示例:https://github.com/joshgeller/react-redux-jwt-auth-example

安全更新: 正如@Dan 在评论中提到的那样,令牌不应该存储在 Localstorage 中,因为每个 javascript 脚本都可以访问那个,这意味着您不拥有的第三方脚本可以访问令牌并用它做任何他们想做的事情。

更好的地方是将其存储为带有 HttpOnly 标志的 Cookie。

【讨论】:

  • 不建议将令牌放入 LocalStorage。见:dev.to/rdegges/please-stop-using-local-storage-1i04
  • @Dan 那么有什么推荐的呢?
  • 让您的服务器将 JWT 令牌保存为 HttpOnly cookie。浏览器将处理其余部分。如果您的前端正在为令牌发出 CORS 请求,则需要为 AJAX 请求设置 withcredentials 标志。
  • 这不应该是选择的答案。将 JWT 存储在 localStorage 中会暴露令牌以进行 xss 攻击。
  • 建议不要将 JWT 放入本地存储是非常值得商榷的。正如@Dan 文章中的一些cmets 指出的那样,这实际上非常好。如果有人能够在您的网站上执行恶意 JS 代码,那么本地存储将是您最不关心的问题......请阅读本文的 cmets,因为文章本身并没有任何公正
【解决方案3】:

由于将 JWT 保存在 localStorage 中容易受到 XSS 攻击,另一种方法可以将其保存在 httpOnly cookie 中,但太糟糕了,您无法在前端执行此操作,请查看 this post。

您唯一的选择是将服务器端配置为在 httpOnly cookie 中返回 JWT,并接受 httpOnly cookie 中的令牌。您还必须考虑如何处理令牌到期。

注意: 虽然现代浏览器支持和阻止通过 httpOnly cookie 读取/写入,但我不确定旧浏览器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2020-10-06
    • 2023-04-01
    • 2021-10-26
    • 1970-01-01
    相关资源
    最近更新 更多