javascript 无法使用Nodejs API验证jwt令牌

dldeef67  于 2023-04-10  发布在  Java
关注(0)|答案(4)|浏览(169)

我正在nodejs/expressjs中处理API,现在我正在使用“JWT令牌”,为此我创建了用于“生成JWT令牌”的函数,现在我想验证该令牌,但我收到以下错误

JsonWebTokenError: jwt malformed

下面是我的当前代码

const secretKey = 'mySecretKey';
const logins = async (req, res) => {
const user = { id: 123, phoneNumber:'123XXXXXXXX' };
  // Create a JWT token with the user payload and the secret key
  const token = jwt.sign(user, secretKey);
  // Return the token to the client
  res.json({ token });
}

function verifyToken(req, res, next) {
 const token = req.body.token;
  if (token) {
    const decode = jwt.verify(token, "secret");
    res.json({
      login: true,
      data: decode,
    });
  } else {
    // Return response with error
    res.json({
      login: false,
      data: "error",
    });
  }
}

关于这个我有几个问题

1) How can we create a common function for all other APIs ( if the token does not match then display an error)
2) How can we verify the token?
pgx2nnw8

pgx2nnw81#

欢迎来到StackOverflow!

  • 要验证jwt令牌,请在此处使用jwt.verify();方法,将第一个参数传递为您正在请求的内容,第二个参数为secretKey
  • 在.env文件中添加secretKey

例如:

secretKey=mySecretKey // env file
const jwt = require("jsonwebtoken");
require("dotenv").config();

const verifyToken = (req, res, next) => {
  const token = req.headers["authorization"];
  if (!token) {
    return res.send("Token is required");
  }
  try {
    const decoded = jwt.verify(token, config.secretKey); // here config.secretKey is what is defined in .env file  
    req.user = decoded; // req.user will store the decoded token
  } catch (err) {
    return res.send("Invalid token"); // if token not match
  }
  return next();
 }
 module.exports = { verifyToken };
  • 如何用路由实现它
const { verifyToken} = require("...."); // import the file

router.get("/list_user", verifyToken, async (req, res) => {
  try{
    console.log(req.user.id); // print the decoded user id
    console.log(req.user.phoneNumber); // print the decoded phone no.

} catch(err){
   return res.send(err.stack)
}
})
w6lpcovy

w6lpcovy2#

jwt malformed是一个错误,当令牌为null或具有无效签名时会发生。在您的示例中,您具有无效签名,您应该更改这行代码:

const decode = jwt.verify(token,"mySecretKey");

为了验证令牌,您需要传递2个参数:
1.token(就像你做的那样)
1.secrety key。您的代码中使用密钥'mySecretKey'创建token,然后尝试使用密钥"secret"进行验证,这是不正确的。您应该使用相同的密钥进行签名和验证。
查看此问题以获取更多信息:Json Web Token verify() return jwt malformed
关于你的问题How can we create common function for all other api,最简单的方法是将代码 Package 在try/catch块中,如果验证失败,则发送错误。

function verifyToken(req, res, next) {
  try {
    const token = req.body.token;
    if (token) {
      const decode = jwt.verify(token, "mySecretKey");
      return res.json({
        login: true,
        data: decode,
      });
    } else {
      // Return response with error
      return res.json({
        login: false,
        data: "error",
      });
    }
  } catch (error) {
    return res.status(500).send(error);
  }
}
lnvxswe2

lnvxswe23#

根据示例中的代码,来自logins的响应中包含的token使用值为'mySecretKey'的密钥进行签名。然而,在verifyToken函数中,您从jwt调用verify方法,同时传递"secret"作为密钥,这与令牌最初签名时使用的不同。因此,您得到的错误是预期的。
为了解决这个问题,在sign和verify方法中使用相同的密钥。我想这也回答了问题(2)。
对于问题(1),您可以使用授权中间件,它位于传入的HTTP请求和实际的请求处理程序之间。通常的做法是在请求头中传递JWT令牌。中间件的代码可能如下所示:

const authMiddleware = (req, res, next) => {
  const authHeader = req.headers.authorization;

  if (!authHeader) {
    return res.status(401).json({ message: 'No authorization header provided' });
  }

  const token = authHeader.split(' ')[1]; // The header format is "Bearer <token>"

  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }

  try {
    // Verify the token using the secret key
    const decoded = jwt.verify(token, mySecretKey);

    // Store the decoded token (user data) in the request object for further use
    req.user = decoded;

    // Proceed to the next middleware or request handler
    next();
  } catch (error) {
    return res.status(401).json({ message: 'Invalid token' });
  }
};

然后,在定义应用路由的文件中,可以包含以下代码,例如:

// Protected route
app.get('/protected', authMiddleware, (req, res) => {
  res.send('This is a protected route');
});

如果你想了解更多关于JWT令牌的信息,请查看这里的资源:https://jwt.io/introduction

drnojrws

drnojrws4#

因此,为了在任何地方使用验证而不重写它,您需要将其用作中间件,如下所示:

function verifyToken(req, res, next) {
  try {
    const token = req.body.token;
    if (token) {
      const decode = jwt.verify(token, "mySecretKey");
      // The next function will have access to this
      req.decode=decode;
      // If the decode is successful you will continue to the next function
      next();
    } else {
      // Return response with error
      return res.json({
        login: false,
        data: "error",
      });
    }
  } catch (error) {
    return res.status(500).send(error);
  }
}

例如,您想调用addrecord。在服务器文件中,您将使用app.use(verifyToken,addRecord)。这意味着在调用addRecord函数之前,将首先调用verifyToken函数,只有当它验证令牌时,它才会继续调用addRecord函数。此外,您现在可以通过使用
const decode=req.decode;在这里查看一些示例:

相关问题