首页 > 解决方案 > Node JS:JWT verify vs redis 查询性能比较?

问题描述

我已经实现了 JWT 令牌,用于对使用 node.js 提供的 API 进行身份验证。

在发送到服务器的每个请求上,我都会执行一次,jwt.verify()但我想知道这是否会占用更多 CPU 资源,因此与将令牌存储在 Redis 中并检索用户 ID 相比,它的可扩展性是否更低。

例子:

const jwt = require('jsonwebtoken')
const app = require('express')

app.get('/user',(req, res) => {
   const { headers: { authorization } } = req
   let token = null
   if (authorization && authorization.split(' ')[0] === 'Bearer') {
     token = authorization.split(' ')[1]
   }
   jwt.verify(token, process.env.TOKEN_SECRET, (err, decoded) => {
      if(err || !decoded){
         return res.json({success: false, message: `Not valid token`})
      }
      //
      // Continue with my logic
      //
   })
})

所以我想知道是否有人知道这样做是否jwt.verify()比 a更好redis.get()

标签: node.jsredisjwt

解决方案


我认为这是一个有待商榷的话题,但答案在很大程度上取决于您要实现的目标/您使用的硬件/您计划如何扩展(正如您提到的可扩展性)

TL;DRjwt.verify()如果它不会导致当前负载出现性能问题,我会坚持使用

  1. 对于使用 HS256 算法创建的常规 JWT 令牌,jwt.verify()它不是在现代 CPU 上运行时间小于 1 毫秒的 CPU 密集型任务

  2. 对于 Redis 案例,我们需要考虑两种情况

    • 我们在同一台机器上运行一个 Redis 实例,这样我们就不必进行网络调用并在延迟上浪费时间或处理网络错误的风险。但是我们无论如何都会引入延迟,因为 2 个独立的进程必须相互通信,但它会是相同的 <1ms

    • 我们有一个全球 Redis 服务器/集群来存储我们的 JWT 令牌,我们必须处理网络问题并将延迟增加到 30-50 毫秒甚至更多

  3. 此外,当我们将 Redis 引入我们的系统时,我们会为我们的系统创建一个额外的复杂层,该层必须维护等等。

尽管Redis 带来了额外的复杂性,但更多的是面向 Node.js 的理念,即尽可能地使一切异步,并且不要因繁重的任务而锁定 CPU(EventLoop)。

但是使用 Redis 方法,我们有点失去了 JWT 本身的优势(我们的 userId 已经在令牌中加密),也许我们需要看看使用会话来存储 userId 而不是 JWT 的解决方案。在大多数情况下,我们需要在令牌过期时将 JWT 存储在某个地方,并且我们需要访问刷新令牌以创建新的 JWT。

因此,我认为最好的方法是坚持下去,jwt.verify()如果它不会导致当前负载出现性能问题(例如您的服务器并非一直以峰值水平使用,但这是另一个需要讨论的问题和主题)

PS 您可以使用 Node APIprocess.hrtime()来简单地衡量运行代码的性能


推荐阅读