首页 > 解决方案 > 通过 express 处理 jwt 令牌返回错误“const token = req.cookies.auth; [0] ^ [0] [0] ReferenceError: req is not defined”

问题描述

我正在尝试完成 jwt 登录我正在尝试在登录中创建 jwt 令牌。然后我正在尝试在我的用户问题路由中使用它。

我正在使用反应前端。

这是正确的方法吗?

我目前收到错误

const token = req.cookies.auth;
[0]               ^
[0]
[0] ReferenceError: req is not defined

下面是我的路由登录代码,一旦我的 sql 服务器返回电子邮件和密码的值存在,它就会分配令牌。用户问题尝试使用此 jwt。我还包括了如何在函数中验证令牌

验证用户

app.get("/user-questions", verifyToken, function(req, res) {
  app.use(function(req, res, next) {
    // decode token
    if (token) {
      jwt.verify(token, "secret", function(err, token_data) {
        if (err) {
          console.info("token did not work");
          return res.status(403).send("Error");
        } else {
          req.user_data = token_data;
          sql.connect(config, function(err) {
            if (err) console.log(err);

            // create Request object
            var request = new sql.Request();

            // query to the database and get the records
            request.execute("dbo.ViewQuestions", function(err, recordset) {
              if (err) console.log(err);

              // send records as a response

              res.json(recordset);
              next();
            });
          });
        }
      });
    } else {
      console.info("no token");
      console.log("no token");
      return res.status(403).send("No token");
    }
  });
});

登录路径

app.post("/login", async (req, response) => {
  try {
    await sql.connect(config);

    var request = new sql.Request();
    var Email = req.body.email;
    var Password = req.body.password;

    console.log({ Email, Password });

    request.input("Email", sql.VarChar, Email);
    request.input("Password", sql.VarChar, Password);

    var queryString =
      "SELECT * FROM TestLogin WHERE email = @Email AND password = @Password";

    //"SELECT * FROM RegisteredUsers WHERE email = @Email AND Password = HASHBYTES('SHA2_512', @Password + 'skrrt')";

    const result = await request.query(queryString);

    if (result.recordsets[0].length > 0) {
      console.info("/login: login successful..");
      console.log(req.body);

      token = jwt.sign(
        { Email },
        "secretkey",
        { expiresIn: "30s" },
        (err, token) => {
          res.json({
            token
          });
          res.cookie("auth", token);
          res.send("ok");
        }
      );
    } else {
      console.info("/login: bad creds");
      response.status(400).send("Incorrect email and/or Password!");
    }
  } catch (err) {
    console.log("Err: ", err);
    response.status(500).send("Check api console.log for the error");
  }
});

验证用户


// Verify Token
function verifyToken(req, res, next) {
  // Get auth header value
  const bearerHeader = req.headers["authorization"];
  // Check if bearer is undefined
  if (typeof bearerHeader !== "undefined") {
    // Split at the space
    const bearer = bearerHeader.split(" ");
    // Get token from array
    const bearerToken = bearer[1];
    // Set the token
    req.token = bearerToken;
    // Next middleware
    next();
  } else {
    // Forbidden
    res.sendStatus(403);
  }
}

请告知这在理论上是否可行。如果没有,请告知如何解决。

编辑 :

该错误已得到解决,但现在我的 jwt 令牌无法正常工作。当登录并手动路由到用户问题时,它不会加载组件,并且在控制台中显示 403 不可用(这是在 jwt 令牌不起作用时在代码中设置的)。

更新:

我将如何包括

 ['authorization'] = 'Bearer ' + token;

进入


 handleSubmit(e) {
    e.preventDefault();
    if (this.state.email.length < 8 || this.state.password.length < 8) {
      alert(`please enter the form correctly `);
    } else {
      const data = { email: this.state.email, password: this.state.password };

      fetch("/login", {
        method: "POST", // or 'PUT'
        headers: {
          Accept: "application/json, text/plain, */*",
          "Content-Type": "application/json",

        },
        body: JSON.stringify(data)
      })
        // .then(response => response.json())
        .then(data => {
          console.log("Success:", data);


        })

        .catch(error => {
          console.error("Error:", error);
        });
    }
  }

标签: javascriptnode.jsexpressjwt

解决方案


您的代码有几个错误:

  • 在您的/login路线中:
    • 您正在尝试在发送响应后设置“auth”cookie
    • 您尝试发送响应两次,一次通过res.json,一次通过res.send
    • 您正在分配一个token不再存在的变量 ( token = jwt.sign(...))
  • 在你的verifyToken方法中:
    • 此方法仅验证请求是否设置了令牌,而不是验证或解码它。我会考虑将您的jwt.verify()电话转移到此方法。
  • 在您的/user-questions路线中:
    • 当这两个都打算在根级别调用时,您正在调用app.useinside 。app.get删除你的app.use电话。
    • 您需要token从请求中获取,例如。const { token } = req;
    • 您正在通过 发送回复res.json(),但之后您仍在致电next()。来自Express 文档

      如果当前中间件函数没有结束请求-响应周期,它必须调用 next() 将控制权传递给下一个中间件函数。


这就是我将如何进行这些更改:

  • /login路线:
app.post("/login", async (req, response) => {
  try {
    await sql.connect(config);

    var request = new sql.Request();
    var Email = req.body.email;
    var Password = req.body.password;

    console.log({ Email, Password });

    request.input("Email", sql.VarChar, Email);
    request.input("Password", sql.VarChar, Password);

    var queryString =
      "SELECT * FROM TestLogin WHERE email = @Email AND password = @Password";

    //"SELECT * FROM RegisteredUsers WHERE email = @Email AND Password = HASHBYTES('SHA2_512', @Password + 'skrrt')";

    const result = await request.query(queryString);

    if (result.recordsets[0].length > 0) {
      console.info("/login: login successful..");
      console.log(req.body);

      jwt.sign(
        { Email },
        "secretkey",
        { expiresIn: "30s" },
        (err, token) => res.cookie('auth', token).json({ token })
      );
    } else {
      console.info("/login: bad creds");
      response.status(400).send("Incorrect email and/or Password!");
    }
  } catch (err) {
    console.log("Err: ", err);
    response.status(500).send("Check api console.log for the error");
  }
});
  • verifyToken方法:
// Verify Token
function verifyToken(req, res, next) {
  // Get auth header value
  const bearerHeader = req.headers["authorization"];
  // Check if bearer is undefined
  if (typeof bearerHeader !== "undefined") {
    // Split at the space
    const bearer = bearerHeader.split(" ");
    // Get token from array
    const bearerToken = bearer[1];

    // verify the token and store it
    jwt.verify(bearerToken, "secret", function(err, decodedToken) {
      if (err) {
        console.info("token did not work");
        return res.status(403).send("Error");
      }

      // Set the token
      req.token = bearerToken;
      req.decodedToken = decodedToken;

      next();
    });
  } else {
    // Forbidden
    res.sendStatus(403);
  }
}
  • /user-questions路线:
app.get("/user-questions", verifyToken, function(req, res) {
  // if a request has made it to this point, then we know they have a valid token
  // and that token is available through either req.token (encoded)
  // or req.decodedToken

  sql.connect(config, function(err) {
    if (err) console.log(err);

    // create Request object
    var request = new sql.Request();

    // query to the database and get the records
    request.execute("dbo.ViewQuestions", function(err, recordset) {
      if (err) console.log(err);

      // send records as a response

      res.json(recordset);
    });
  });
});

推荐阅读