TypeError:无法读取 node.js 中未定义的属性(读取“split”)

问题描述 投票:0回答:1

无法重新生成令牌,split 中的一个问题。错误,显示拆分未定义。如何解决拆分问题。下面提到我的代码和问题。如何解决拆分问题?这里如何从现有代码重新生成令牌?

错误:TypeError:无法读取 node.js 中未定义的属性(读取“split”)

以下代码出现错误:

 const cookies = request.headers.cookie;
 const token = cookies.split('=')[1] 

server.js代码:

const dotenv = require('dotenv').config()
const express = require('express')
const app = express()
const connectDB = require('./config/db')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const cors = require('cors')

app.use(cookieParser()) //cookie parser is used to protect user details from hacker
//middleware - urlencoded for form submission & json for api calling
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json({extended:true}))
//app.use(cookieParser());
//app.use(express.json())

app.use(cors({ credentials: true, origin: "http://localhost:3000" }))

//router
app.use('/api/employee', require('./routes/employeeRoute'))
app.use('/api/user', require('./routes/userRoute'))

// mongodb connection
connectDB()

// port connection
PORT = process.env.PORT
app.listen(PORT, () => console.log(`Listening to port number: ${PORT}`))

userRouter.js

const express = require('express');
const userController = require('../controllers/userController')
const router = express.Router();

router.post('/signup', userController.signup);
router.post('/login',userController.Login);
router.get('/profile',userController.verifyToken,userController.getUser);
//verify token is used for after refresh the page, user can able to view user details.
router.get('/refresh',userController.refreshToken,userController.verifyToken,userController.getUser)
router.post('/logout', userController.Logout)
 module.exports = router;

用户控制器.js

const User = require('../models/userModel');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
//const { request, response } = require('express');
//const JWT_SECRET_KEY = 'secret key'

// Registration for new user
//next is used for next step of middleware
const signup = async (request, response, next) => {
    const { name, email, password } = request.body;
    let existingUser;
    try {
        existingUser = await User.findOne({ email: email })
    } catch (error) {
        console.log(error)
    }
    if (existingUser) {
        console.log('User already exists', existingUser)
        return response.status(400).json({ message: 'User already exists! Login Instead' })
    }
    const hashedPassword =  bcrypt.hashSync(password)
    const newuser = new User({
        name, // name: name , password: password
        email,
        password: hashedPassword
    })
    try {
        await newuser.save()
    } catch (error) {
        console.log(error)
    }

    return response.status(201).json({ message: newuser })
}

//Login user after registration
const Login = async (request, response, next) => {
    const { email, password } = request.body;

    let existingUser;
    try {
        existingUser = await User.findOne({ email: email })
    } catch (error) {
        console.log(error)
        return new Error(error)
    }

    if (!existingUser) {
        return response.status(400).json({ message: 'User not found. Signup please...' })
    }

    const isPasswordCorrect = bcrypt.compareSync(password, existingUser.password)

    if (!isPasswordCorrect) {
        return response.status(400).json({ message: 'Invalid email or password' })
    }
    //HSA256 token
    const token = jwt.sign({ id: existingUser._id }, process.env.JWT_SECRET_KEY, {
        expiresIn: '1h'
    })

    console.log("Generated Token\n", token);
    if(request.cookies[`${existingUser._id}`]){
        request.cookies[`${existingUser._id}`] = "";
    }

    response.cookie(String(existingUser.id),token,{
        path:'/',
        expires: new Date(Date.now() + 1000 * 30), // 30 seconds
        httpOnly: true, // it is overall accessable from frontend
        sameSite: 'lax'
    })
    return response.status(200).json({ message: 'Successfully Logined In', user: existingUser, token })
}

//baerer token is used authorization
const verifyToken = (request, response, next) => { // verify the user token
   
    // const headers = request.headers[`authorization`];
    //  //console.log('token',headers)
     // generate token to the login user
    //const token = headers.split(" ")[1]
    const cookies = request.headers.cookie;
    const token = cookies.split('=')[1]    // split the token for verify the token,here zero index contain 1st element. 
    //console.log(token);
    if (!token) {
        response.status(404).json({ message: 'No token found' });
    }
    // decode information indicated as user
    jwt.verify(String(token), process.env.JWT_SECRET_KEY, (error, user) => {
        if (error) {
            console.log('Invalid Token')
            return response.status(400).json({ message: 'Invalid Token' })
        }
        console.log(user.id);
        request.id = user.id; // decoded the id
    })
    next()//next is used to move next middleware getUser
}

const getUser = async (request, response, next) =>{
    const userId = request.id;
    let user;
    try {
        user = await User.findById(userId,"-password") // -password is used for display all details of user without password

    } catch (error) {
        return new Error(error)
    }
    // validate  
    if(!user){
        return response.status(404).json({message:'User Not Found'})
    }
    return response.status(200).json({user})
}

const refreshToken = (request, response, next) => { 
    const cookies = request.headers.cookie;
    const prevToken = cookies.split("=")[1];
    if (!prevToken) {
      return response.status(400).json({ message: "Couldn't find token" });
    }
    jwt.verify(String(prevToken), process.env.JWT_SECRET_KEY, (err, user) => {
      if (err) {
        console.log(err);
        return response.status(403).json({ message: "Authentication failed" });
      }
      response.clearCookie(`${user.id}`);
      request.cookies[`${user.id}`] = "";
  
      const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET_KEY, {
        expiresIn: "35s",
      });
      console.log("Regenerated Token\n", token);
  
      response.cookie(String(user.id), token, {
        path: "/",
        expires: new Date(Date.now() + 1000 * 30), // 30 seconds
        httpOnly: true,
        sameSite: "lax",
      });
  
      request.id = user.id;
      next();
    });
  };
  
const Logout = async (request,response,next)=>{
    const cookies = request.headers.cookie;
    const prevToken = cookies.split("=")[1];
    if (!prevToken) {
      return response.status(400).json({ message: "Couldn't find token" });
    }
    jwt.verify(String(prevToken), process.env.JWT_SECRET_KEY, (err, user) => {
      if (err) {
        console.log(err);
        return response.status(403).json({ message: "Authentication failed" });
      }
      response.clearCookie(`${user.id}`);
      request.cookies[`${user.id}`] = "";
      return response.status(200).json({message:' Successfully Logout'})
      
    });
}

module.exports = { signup, Login, verifyToken , getUser, refreshToken, Logout}

错误:

Generated Token
 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzZmUxMjMzNWRkYjBjZmNhYjZmY2I3ZCIsImlhdCI6MTY3ODExNDc1OCwiZXhwIjoxNjc4MTE4MzU4fQ.HVMpX6qUH6_lcAVM8IHRdrLtWSqpIQW3nGJtbfM1UiY  
63fe12335ddb0cfcab6fcb7d
TypeError: Cannot read properties of undefined (reading 'split')
    at verifyToken (F:\react class\project_employee\backend\controllers\userController.js:84:27)
    at Layer.handle [as handle_request] (F:\react class\project_employee\backend\node_modules\express\lib\router\layer.js:95:5)
    at next (F:\react class\project_employee\backend\node_modules\express\lib\router\route.js:144:13)
    at Route.dispatch (F:\react class\project_employee\backend\node_modules\express\lib\router\route.js:114:3)      
    at Layer.handle [as handle_request] (F:\react class\project_employee\backend\node_modules\express\lib\router\layer.js:95:5)
    at F:\react class\project_employee\backend\node_modules\express\lib\router\index.js:284:15
    at Function.process_params (F:\react class\project_employee\backend\node_modules\express\lib\router\index.js:346:12)
    at next (F:\react class\project_employee\backend\node_modules\express\lib\router\index.js:280:10)
    at Function.handle (F:\react class\project_employee\backend\node_modules\express\lib\router\index.js:175:3)     
    at router (F:\react class\project_employee\backend\node_modules\express\lib\router\index.js:47:12)
node.js mongodb express mern
1个回答
0
投票

一旦您能够存储或收集用户的 cookie,您就不会有任何问题。在这里,您正试图从可能并不总是可用的 cookie 中获取令牌。如果我正确理解了方法名称,那么您正在尝试获取并验证令牌,您不需要为此解析 cookie。

这是我在我的应用程序中使用的实现。请尝试一下,看看它是否能解决您的问题。

import jwt from "jsonwebtoken";

export const verifyToken = async (req, res, next) => {
  try {
    let token = req.header("Authorization");

    if (!token) {
      return res.status(403).send("Access Denied");
    }

    if (token.startsWith("Bearer ")) {
      token = token.slice(7, token.length).trimLeft();
    }

    const verified = jwt.verify(token, process.env.JWT_SECRET);
    req.user = verified;
    next();
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
};

© www.soinside.com 2019 - 2024. All rights reserved.