简体   繁体   English

JWT 来自一个网站的无效签名,但另一个网站没有错误。 用户对象的额外属性被添加到令牌中

[英]JWT Invalid signature from one website, but no errors with another. Extra properties of user object get added to token

Problem问题

I have two websites.我有两个网站。 One is production, but a very very old version.一个是生产,但一个非常非常旧的版本。 Another is just localhost where I'm currently testing it.另一个只是我目前正在测试的本地主机。 After involving NextAuthJS to the NextJS website, I need to integrate my NextAuthJS session provider to the remote ExpressJS backend.NextAuthJS引入 NextJS 网站后,我需要将 NextAuthJS 会话提供程序集成到远程 ExpressJS 后端。

  1. I make a request to /login ->我向 /login -> 提出请求

    1. on remote backend I generate a JWT token, and get full user details.在远程后端我生成一个 JWT 令牌,并获取完整的用户详细信息。
    2. then I send data to the NextJS website.然后我将数据发送到 NextJS 网站。
    3. using NextAuthJS, store it in a cookie.使用 NextAuthJS,将其存储在 cookie 中。

  1. In case I need to get any user specific details, such as saved videos:如果我需要获取任何用户特定的详细信息,例如保存的视频:

    1. I make a request from NextJS website.我从 NextJS 网站提出请求。
    2. On remote ExpressJS backend I decode the token which I receive in the 'authorization' bearer header, to get user's details...在远程 ExpressJS 后端,我解码我在“授权”承载标头中收到的令牌,以获取用户的详细信息...

And boom!和繁荣! Here the error message repeats shouting at me: "JsonWebTokenError: invalid signature"这里的错误消息重复对我大喊:“JsonWebTokenError:无效签名”

That doesn't happen on the production website, even though the remote backend is one link for both the production and development.这不会发生在生产网站上,即使远程后端是生产和开发的一个链接。

What I have tried and explored我所尝试和探索的

What I noticed using JWT token debugger is that我在使用JWT 令牌调试器时注意到的是

  1. In case of the production website's request, which doesn't give any errors, the decoded user consists of { id, role }.如果生产网站的请求没有给出任何错误,则解码的用户由 { id, role } 组成。 As EXPECTED.正如预期的那样。 jwt 解码器的屏幕截图
  2. But in case of local version's request, which gives error message, it shows that the user consists of the whole user details object stored in the DB.但是在本地版本的请求的情况下,它给出了错误消息,它表明用户由存储在数据库中的整个用户详细信息对象组成。 And debugger also changes the decryption algorithm automatically from HS256 to HS512.并且调试器还会自动将解密算法从 HS256 更改为 HS512。 And, even though showing the encrypted message, it says 'token verification failed'.而且,即使显示加密消息,它也会显示“令牌验证失败”。 JWT 令牌调试器

Token from local, gives error: eyJhbGciOiJIUzUxMiJ9..ZCnnNZ2a7aeO6GCnyhnWYGMX-4kkJX75ZyzG52lSiWxUBIawXrA37882HFwo_3r6-I3JrrYNv270vxfsMwyBlw来自本地的令牌,给出错误: eyJhbGciOiJIUzUxMiJ9..ZCnnNZ2a7aeO6GCnyhnWYGMX-4kkJX75ZyzG52lSiWxUBIawXrA37882HFwo_3r6-I3JrrYNv270vxfsMwyBl


Token from production, works as expected : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTY3MywiZXhwIjoxNjM2Mzc4MDczfQ.bqY6y0_lmX5dBAHemgv_9UFuupwLBBDcyFpAdXgCiH8从生产令牌,按预期工作:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTY3MywiZXhwIjoxNjM2Mzc4MDczfQ.bqY6y0_lmX5dBAHemgv_9UFuupwLBBDcyFpAdXgCiH8


JWT Secret : jdgfaiodsugfaileufliaeruy JWT 秘密:jdgfaiodsugfaileufliaeruy


Code of decoding token and getting user data is:解码token获取用户数据的代码为:

exports.requireSignin = (req, res, next) => {
  if (req.headers.authorization) {
    const token = req.headers.authorization.split(" ")[1];
    console.log( 'token is', token );
    jwt.verify(token, process.env.JWT_SECRET, function (err, decoded) {
      if (err) {
        console.log( err, 'Token given', token, 'Token secret', process.env.JWT_SECRET );
        return res.status(401).json({ error: "Token has been expired!" });
      }
      req.user = decoded;
      console.log( decoded );
    });
    // const user = jwt.verify(token, process.env.JWT_SECRET);
    // console.log(user);
    // req.user = user;
  } else {
    return res.status(401).json({ error: "Authorization required" });
  }
  next();
  //jwt.decode()
};

Code of GENERATING that token:生成该令牌的代码:

exports.signin = async (req, res) => {
  
  
  User.findOne({ email: req.body.email }).exec((error, user) => {
    if (error){ console.log( 'login error', error ); return res.status(400).json({ error }); }
   
    if (user) {
      bcrypt.compare(req.body.password, user.hash_password, (err, result) => {
        if (err) {
            console.log( req.body.password, user.hash_password );
          return res
            .status(400)
            .json({ error: "Something's wrong, Please try again" });
        }
        if (!result) {
          return res.status(400).json({ error: "Invalid credentials" });
        }

        if (user.approval.isApproved === false)
          return res
            .status(400)
            .json({ error: "Please verify your account" });

        if (user.isSuspended === true)
          return res.status(400).json({ error: "You have been temporarily suspended, please contact support" });

        const token = jwt.sign(
          { _id: user._id, role: user.role },
          process.env.JWT_SECRET,
          {
            expiresIn: "1d",
          }
        );
        console.log( process.env.JWT_SECRET, token, user._id, user.role );

        // some unnecessary code ...

          res.status(200).json({
            success: true,
            token: "Bearer " + token,
            ProfileImageBaseUrl: ProfileImageBaseUrl,
            user: {
              _id,
              firstName,
              lastName,
              email,
              role,
              jobRole,
              videoGoal,
              profilePicture,
              createdBy,
              approval,
              accessType,
              resetPassToken,
              branding,
              sub_status
            },
          });

           
            
        })
       
      });
    } else {
      return res.status(400).json({ error: "Something's wrong, Please try again" });
    }
  });
};

A) WHEN I GET AN ERROR, The LOGS I receive from my backend are: A) 当我收到错误时,我从后端收到的日志是:


Sign in controller , console.log( process.env.JWT_SECRET, token, user._id, user.role ) is登录控制器,console.log( process.env.JWT_SECRET, token, user._id, user.role ) 是

jdgfaiodsugfaileufliaeruy eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTY3MywiZXhwIjoxNjM2Mzc4MDczfQ.bqY6y0_lmX5dBAHemgv_9UFuupwLBBDcyFpAdXgCiH8 617c1a37a0b032117153d473 user jdgfaiodsugfaileufliaeruy eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTY3MywiZXhwIjoxNjM2Mzc4MDczfQ.bqY6y0_lmX5dBAHemgv_9UFuupwLBBDcyFpAdXgCiH8 617c1a37a0b032117153d473用户


Require sign in controller ,console.log( err, 'Token given', token, 'Token secret', process.env.JWT_SECRET ) is:需要登录控制器,console.log(err, 'Token given', token, 'Token secret', process.env.JWT_SECRET ) 是:

Token given eyJhbGciOiJIUzUxMiJ9..ZCnnNZ2a7aeO6GCnyhnWYGMX-4kkJX75ZyzG52lSiWxUBIawXrA37882HFwo_3r6-I3JrrYNv270vxfsMwyBlw Token secret jdgfaiodsugfaileufliaeruy给定的令牌 eyJhbGciOiJIUzUxMiJ9..ZCnnNZ2a7aeO6GCnyhnWYGMX-4kkJX75ZyzG52lSiWxUBIawXrA37882HFwo_3r6-I3JrrYNv270vxfsMwyBlwfagia Token secret


B) When no error, these are: B) 当没有错误时,这些是:


Require sign in : token is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTYyNSwiZXhwIjoxNjM2Mzc4MDI1fQ.K-inQfI77mepKjkG_5g4obr3sfcVnDwCOXeQlDPra00需要登录:令牌eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTYyNSwiZXhwIjoxNjM2Mzc4MDI1fQ.K-inQfI77mepKjkG_5g4obr3sfcVnDwCOXeQlDPra00


Sign in :登录

jdgfaiodsugfaileufliaeruy eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTYyNSwiZXhwIjoxNjM2Mzc4MDI1fQ.K-inQfI77mepKjkG_5g4obr3sfcVnDwCOXeQlDPra00 617c1a37a0b032117153d473 user jdgfaiodsugfaileufliaeruy eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdjMWEzN2EwYjAzMjExNzE1M2Q0NzMiLCJyb2xlIjoidXNlciIsImlhdCI6MTYzNjI5MTYyNSwiZXhwIjoxNjM2Mzc4MDI1fQ.K-inQfI77mepKjkG_5g4obr3sfcVnDwCOXeQlDPra00 617c1a37a0b032117153d473用户

My thoughts我的想法

I feel like it is just something simple I just don't notice, I've been trying to fix it for 9 hours, but I haven't determined what yet.我觉得这只是一些我没有注意到的简单事情,我已经尝试修复了 9 个小时,但我还没有确定是什么。

Please, help me, guys!请帮帮我,伙计们!

Any help or hints are highly appreciated!任何帮助或提示都非常感谢!

Thank you so much in advance!非常感谢您!

Thanks everyone who helped me with this!感谢所有帮助过我的人! @Bergi and @eol! @Bergi 和 @eol!

The problem was nextauthjs specific and not conserned about expressjs, as it appeared.问题是 nextauthjs 特定的,而不是像它出现的那样关注 expressjs。

So I don't get token returned by nextauthjs anymore.所以我不再得到 nextauthjs 返回的令牌。

Instead, I get token from user object's authToken property, stored in the session.相反,我从存储在会话中的用户对象的 authToken 属性获取令牌。


So it is like:所以它就像:

MyApp.getInitialProps = async ({ router, ctx }) => {
  const session = await getSession(ctx);
  if (router.asPath === '/login' || router.asPath === '/register') {
    return { session: session };
  }
  if (!session || !session.user) {
    ctx.res.writeHead(302, {
      Location: '/login',
    });
    ctx.res.end();
  }
  console.log('Access token', session.accessToken);
  axios.defaults.headers.common = {
    authorization: `${session.accessToken}`,
  };
  return { token: `${session.accessToken}`, session: session };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将元素从一个数组复制到另一个数组时出现 Javascript 问题。 额外的方括号,额外的尺寸? - Javascript trouble when copying element from one array to another. Extra square brackets, extra dimensions? 从一个组件中获取价值,并在另一个组件中使用它。 - Get value from one component and use it in another. 如何从一个表中获取 id 并将其插入到另一个表中。 postgresql - how to get id from one table and insert it into another. postgresql 尝试将属性从一个 object 分配给另一个时出现 TypeScript 错误 - TypeScript errors while trying to assign properties from one object to another 将一种模式用于另一种模式。 获取 TypeError:无效的架构配置 - Using one schema into another. Getting TypeError: Invalid schema configuration 用户单击一个元素时,触发另一个单击。 - When user clicks on one element, trigger a click on another. 将一个图像淡入另一个图像。 - Fade one image into another. 从一个函数发送一个随机数,以供另一个函数使用。 - Send a random number from one function to be used by another. 将元素从一个数组移动到另一个数组。 (JavaScript) - Moving elements from one array to another. (JavaScript) 通过给定一个获得另一个JSON对象属性 - get another JSON object properties by given one
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM