使用 jsonwebtoken 在 MERN 堆栈中生成令牌并在前端和后端之间传递时出错

Error while generating token and passing it between frontend and backend in MERN stack using jsonwebtoken

错误:

TypeError: Cannot read property 'jwtoken' of undefined

概览: 每当用户登录他的帐户时,都会使用 JSONwebtoken 生成一个令牌。然后将此令牌传递到后端。 'about page' 存储在 cookie 中的 token 必须与存储在数据库中的 token 进行验证(token 在用户登录时生成并存储在数据库中)后才能看到

代码(后端文件):

authenticate.js(中间件)

const authenticate = async (req, res, next) => {
  try {
    const token = req.cookies.jwtoken;  //this line throws an error
...//more code

auth.js: (路由器文件)

router.post("/signin", async (req, res) => {
  let token;
  const { email, password } = req.body;

  if (!email || !password) {
    return res.status(422).json({ error: "invalid creds" });
  }

  try {
    const userLogin = await User.findOne({ email: email });

    if (!userLogin) {
      return res.status(422).json({ error: "invalid email" });
    } else {
      token = await userLogin.generateAuthToken();

      res.cookie("jwtoken", token, {
        expires: new Date(Date.now() + 2592000000),
        httpOnly: true,
      });

      const isMatch = await bcrypt.compare(password, userLogin.password);
      if (!isMatch) {
        return res.status(422).json({ error: "invalid password" });
      }
      res.status(201).json({ msg: "login successful" });
    }
  } catch (error) {
    console.log(error);
  }
});

router.get("/about", authenticate, (req, res) => { //authenticate is middleware
  res.send(req.rootUser);
});

userSchema.js-> 令牌已生成,数据库模型架构

  try {
    let tokenVal = jwt.sign({ _id: this._id }, process.env.SECRET_KEY);
    this.tokens = this.tokens.concat({ token: tokenVal });
    await this.save();
    return tokenVal;
  } catch (err) {
    console.log(err);
  }
};

前端文件:

about.js

const About = () => {
  const history = useHistory();

  const callAboutPage = async () => {
    try {
      const res = await fetch("/about", {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json", 
        },
        credentials: "include", //i.e send cookies
      });

      const data = await res.json();
      console.log(data);

      if (!res.status === 200) {
        const error = new Error(res.error);
        console.log(error);
        throw error;
      }
    } catch (err) {
      console.log(err);
      history.push("/login");
    }
  };

  useEffect(() => {
    callAboutPage();
  });

login.js

onst Login = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const history = useHistory();

  const loginUser = async (e) => {
    e.preventDefault();

    const res = await fetch("/signin", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },

      body: JSON.stringify({
        email,
        password,
      }),
    });
    const data = res.json();
    if (!data || res.status === 422) {
      window.alert("Invalid creds");
    } else {
      window.alert("LOGIN successful");
      history.push("/");
    }
  };
TypeError: Cannot read property 'jwtoken' of undefined
    at authenticate (F:\projects\mern\basicMernProject\server\middleware\authenticate.js:6:31)
    at Layer.handle [as handle_request] (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\layer.js:95:5)
    at next (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\route.js:137:13)        
    at Route.dispatch (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\layer.js:95:5)
    at F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:335:12)
    at next (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:275:10)        
    at Function.handle (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:174:3)
    at router (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:47:12)       
    at Layer.handle [as handle_request] (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:317:13) 
    at F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:335:12)
    at next (F:\projects\mern\basicMernProject\server\node_modules\express\lib\router\index.js:275:10)        
    at jsonParser (F:\projects\mern\basicMernProject\server\node_modules\body-parser\lib\types\json.js:110:7) 

看起来您没有使用任何与 cookie 相关的中间件。默认情况下,Express 不解析请求 cookie headers。这就是为什么您的 req object 没有 cookies 属性。为了让它工作,你应该考虑在初始化你的 express 应用程序时添加一个 cookie-parser 中间件:

// server.js?
const express = require('express')
const cookieParser = require('cookie-parser')

const server = express()
server.use(cookieParser())

此中间件在 req object.

上创建并填充 cookies 属性