我如何存储 JWT 并使用 react 将它们与每个请求一起发送

IT技术 express reactjs passport.js react-router jwt
2021-04-08 06:21:52

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

所以基本上我得到了这个:

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 请求时,我都会保护我的 /admin 路由和 POSTMAN,一切正常。

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

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

多谢你们

3个回答

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

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

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

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

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

3- 我将令牌保存在用户的 localStorage 中

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

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

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

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

让您的服务器将 JWT 令牌保存为 HttpOnly cookie。浏览器将处理其余的。如果您的前端正在为令牌发出 CORS 请求,则需要为 AJAX 请求设置 withcredentials 标志。
2021-05-28 06:21:52
建议不要将 JWT 放在本地存储中是很有争议的。正如@Dan 文章中的一些评论指出的那样,这实际上非常好。如果有人能够在你的网站上执行恶意的 JS 代码,本地存储将是你最不关心的......请阅读这篇文章的评论,因为文章本身并不公平
2021-06-09 06:21:52
这不应该是选定的答案。将 JWT 存储在 localStorage 中将暴露令牌以进行 xss 攻击。
2021-06-11 06:21:52
@Dan 那么推荐什么?
2021-06-16 06:21:52
不建议将令牌放在 LocalStorage 中。请参阅:dev.to/rdegges/please-stop-using-local-storage-1i04
2021-06-19 06:21:52

由于将 JWT 保存在 localStorage 中容易受到 XSS 攻击,另一种方法可以将它保存在 httpOnly cookie 中,但太糟糕了,你不能在前端这样做,请查看这篇文章

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

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