Javascript 节点js、JWT令牌和背后的逻辑

Javascript 节点js、JWT令牌和背后的逻辑,javascript,node.js,express,jwt,express-jwt,Javascript,Node.js,Express,Jwt,Express Jwt,我正在使用JWT来保护节点JSURL 要创建JWT令牌用户会话,我只需执行以下操作: -> auth/signup -> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/}); 或在登录呼叫的情况下 -> auth/login -> jwt.sign(user_profile,secret,expireInMinutes:{90000

我正在使用JWT来保护节点JSURL

要创建JWT令牌用户会话,我只需执行以下操作:

-> auth/signup
    -> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
或在登录呼叫的情况下

 -> auth/login
        -> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
每次调用受保护的url时,我都会检查JWT中间件自动设置的
req.user

现在我想知道:

1-调用sign()时,JWT令牌存储在哪里

2-每次调用受保护的url时,是否必须验证()令牌?如果是,为什么

3-当我为已经签名的用户设置新令牌时,是否会删除旧令牌(如果存在)?如果未设置有效期,或者例如为5年,该怎么办

4-为什么我不能在同一浏览器/应用程序页面上设置新令牌? 如果我注册了一个新的令牌,但该令牌匹配(我已选中),则会出现无效的签名错误 就像我不能在同一个浏览器上登录超过1个用户一样

  • 您需要将令牌存储在客户端(本地存储或cookie)

  • 对。HTTP是无状态的。如果您没有每次都进行验证,可能会有人在没有令牌或令牌无效的情况下调用您的URL。如果您担心性能,HMACSHA256检查非常快

  • 那没有道理,你一定做错了什么


  • 对不起。这应该是对之前答案的评论,但我没有足够的代表来评论,所以他就这么说了


    @SBBAANG:每次验证的另一个原因是可能会有有趣的事情发生“令牌中的请求2,例如允许用户访问某些端点,而不是所有端点。因此,在每次验证中,您不仅要验证用户是否被允许访问受保护的API,还要验证特定的端点,这不是基于是否有有效的令牌,而是基于是否有专门允许它的令牌。

    您必须已经使用其他用户以前的回答找出了您以前所有问题的答案,但我也会尝试为其他人澄清一些事情:

    1-调用sign()时,JWT令牌存储在哪里

    当您调用sign时,签名的令牌不会存储在任何位置,而是存储在任何位置 由sign函数返回,然后必须将其发送到客户端 这样就可以在客户端存储。(例如,会话存储、, 本地存储(或cookie)

    2-每次调用受保护的url时,我是否必须验证()令牌?如果是,为什么

    是的,你知道。想法是一旦客户机拥有令牌,他们将发送 每次发出请求时,令牌都会发送到服务器。代币是 由服务器处理,以确定特定客户端是否具有 已经过身份验证

    3-当我为已经签名的用户设置新令牌时,是否会删除旧令牌(如果存在)?如果没有设定有效期,或者例如5年,该怎么办

    与第1点的答案略有关联。调用sign函数 将只生成另一个令牌。令牌的到期时间为 存储在已签名令牌本身中。因此,每次服务器获取令牌时 从客户端,它检查作为令牌一部分的到期时间 验证。需要注意的是,签名的令牌只是 “user_profile”对象,您在 签名,以及添加到 那个物体

    因此,客户端可以在客户端存储多个令牌。他们 只要它们尚未过期,它们都将有效。但是, 其想法是,仅在客户端收到令牌后才向其发送令牌 旧版本过期后再次验证

    4-为什么我不能在同一浏览器/应用程序页面上设置新令牌?如果我注册了一个新的令牌,但该令牌匹配(我检查过),我会得到无效的签名错误,就像我不能在同一个浏览器上登录多个用户一样

    这个想法是每个浏览器有一个用户。因为在这种情况下,浏览器 他是客户。我想不出您需要的用例 每个浏览器/客户端都有多个用户,所以您显然是这样做的 有点不对劲。这并不是说不可能发送多个 同一浏览器/客户端的令牌

    2-每次启用受保护的url时,是否必须验证()标记 打电话?如果是,为什么

    对。但“验证”这个词有点让人困惑

  • 当客户端调用/验证时,服务器首先根据数据库验证用户凭据,以使该用户通过身份验证。而这个“昂贵”的操作在整个令牌生命周期中只执行一次。然后,服务器准备JSON对象,保存有用的用户信息,并对其进行加密以获得JWT令牌
  • 此令牌只发送一次到客户端,存储在浏览器中,然后在每个客户端请求/api时发送回服务器
  • 在处理客户机/api请求期间,服务器必须“验证”令牌的有效性(JWT会为您进行验证)。但这并不意味着再次根据数据库检查用户凭据。只需解密令牌就可以取回JSON对象,HMAC-SHA256验证——相当快
  • 有了带有有用用户信息(声明)的JSON对象,服务器可以允许或不允许该特定用户访问/api路由下请求的资源 在令牌验证期间,不需要对用户凭据进行数据库检查,因为服务器必须信任收到并验证(成功解密)的令牌。识别用户不需要服务器会话存储


    您可以将JWT令牌想象成一个简单的会话信息,以加密的形式存储在客户机上。但如果您需要在用户会话信息中缓存更多数据,我认为,您仍然需要在服务器上存储某种会话,这使得JWT的想法与Cookie中的传统会话ID相比几乎毫无用处。

    谢谢,我解决了第3/4点,这似乎是我自己的错误;)关于第2点:为什么要验证?我的意思是,/api URL已经被保护了没有?我必须在它们里面添加一个额外的jwt验证吗?我的意思是我尝试用手工制作的头调用一个受/api保护的url,例如authorization:Bearer random\u hand\u make,它正确返回{”消息