微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

错误

TypeError: Cannot read property 'jwtoken' of undefined

概述: 每当用户登录其帐户时,都会使用 JSONwebtoken 生成令牌。然后将此令牌传递给后端。只有在cookies中存储的token与数据库中存储的token(token在用户登录生成并存储在数据库中)进行验证后,用户才能看到“关于页面”。

CODE(后端文件):

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-> token 生成数据库模型schema

  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();
  });

登录.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 部分中也可见

解决方法

看起来您没有使用任何与 cookie 相关的中间件。 Express 默认不解析请求 cookie 标头。这就是您的 req 对象没有 cookies 属性的原因。为了使其工作,您应该考虑在初始化您的 express 应用程序时添加一个 cookie-parser 中间件:

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

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

此中间件在 cookies 对象上创建并填充 req 属性。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。