Express 中间件未定义类型
Express middleware undefined type
我正在尝试为我的快速服务器创建一个身份验证中间件,但在我的 IDE 中没有出现类型错误,但是当我尝试编译时,我得到了 TypeError: Cannot read properties of undefined (reading protect)
。该路由在没有中间件的情况下工作正常,并且中间件没有可检测的 linting 问题。我也在使用 socket.io 所以我尝试了 io.use(wrap(middleware))
以防万一它会起作用但它没有但无论如何那是在黑暗中拍摄的,问题似乎无关紧要。我也尝试用 any
替换所有相关类型声明并遇到同样的问题。
用户控制器:
export const getMe = asyncHandler(async (req: IGetUserAuthInfoRequest, res: Response): Promise<void> => {
res.status(200).json(req.user)
})
路由控制器:
public static protect = asyncHandler(async (req: IGetUserAuthInfoRequest, res: Response, next: NextFunction): Promise<void> => {
let token: string
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
try {
token = req.headers.authorization.split(' ')[1]
const decoded: JwtPayload = jwt.verify(token, process.env.JWT_SECRET, { complete: true })
req.user = await UserModel.findById(decoded.id).select('-password')
next()
} catch (err) {
res.status(401)
throw new Error('Not authorised')
}
}
if (!token) {
res.status(401)
throw new Error('Not a valid token')
}
})
扩展的快速请求接口:
export interface IGetUserAuthInfoRequest extends Request {
user: any
}
用户路由器:
userRouter.route('/me').get(RoutesController.protect, userController.getMe)
错误:
TypeError: Cannot read properties of undefined (reading 'protect')
at Object.<anonymous> (C:\Users\liams\dev\my-rest-server\src\routes\user.router.ts:8:46)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Module._compile (C:\Users\liams\dev\my-rest-server\node_modules\source-map-support\source-map-support.js:568:25)
at Module.m._compile (C:\Users\liams\AppData\Local\Temp\ts-node-dev-hook-8639111545614118.js:69:33)
at Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at require.extensions.<computed> (C:\Users\liams\AppData\Local\Temp\ts-node-dev-hook-8639111545614118.js:71:20)
at Object.nodeDevHook [as .ts] (C:\Users\liams\dev\my-rest-server\node_modules\ts-node-dev\lib\hook.js:63:13)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
[ERROR] 20:08:00 TypeError: Cannot read properties of undefined (reading 'protect')
知道我遗漏了什么吗?
编辑:您可以在存储库中看到它,而不是在这里发布我的代码的每一行:https://github.com/dotDone/my-rest-server/tree/auth
当您在用户控制器中使用它时,您的 RouteController 尚未定义。 (您的架构可以改进,但我只会尝试回答您的问题,只知道有更好的方法来组织所有这些)
尝试以下
将 UserRoutes 转为 class
import { Router } from 'express'
import * as userController from '../controllers/user.controller'
class UserRoutes {
constructor(routesController) {
this.userRouter: Router = Router();
this.routesController = routesController;
this.initRoutes();
}
initRoutes() {
userRouter.route('/').get(userController.getUsers).post(userController.createUser).put(userController.editUser).delete(userController.deleteUser)
userRouter.route('/me').get(this.routesController.protect, userController.getMe)
}
}
然后在您的 server.ts 中创建另一个函数,例如将其称为 initRoutes,您可以在其中执行类似操作
constructor() {
this.startServer().then(() => this.startControllers()).then(() => this.initRoutes()).catch(err => console.log(err))
}
...
initRoutes() {
this.userRoutes = new UserRoutes(this.routesController);
}
我正在尝试为我的快速服务器创建一个身份验证中间件,但在我的 IDE 中没有出现类型错误,但是当我尝试编译时,我得到了 TypeError: Cannot read properties of undefined (reading protect)
。该路由在没有中间件的情况下工作正常,并且中间件没有可检测的 linting 问题。我也在使用 socket.io 所以我尝试了 io.use(wrap(middleware))
以防万一它会起作用但它没有但无论如何那是在黑暗中拍摄的,问题似乎无关紧要。我也尝试用 any
替换所有相关类型声明并遇到同样的问题。
用户控制器:
export const getMe = asyncHandler(async (req: IGetUserAuthInfoRequest, res: Response): Promise<void> => {
res.status(200).json(req.user)
})
路由控制器:
public static protect = asyncHandler(async (req: IGetUserAuthInfoRequest, res: Response, next: NextFunction): Promise<void> => {
let token: string
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
try {
token = req.headers.authorization.split(' ')[1]
const decoded: JwtPayload = jwt.verify(token, process.env.JWT_SECRET, { complete: true })
req.user = await UserModel.findById(decoded.id).select('-password')
next()
} catch (err) {
res.status(401)
throw new Error('Not authorised')
}
}
if (!token) {
res.status(401)
throw new Error('Not a valid token')
}
})
扩展的快速请求接口:
export interface IGetUserAuthInfoRequest extends Request {
user: any
}
用户路由器:
userRouter.route('/me').get(RoutesController.protect, userController.getMe)
错误:
TypeError: Cannot read properties of undefined (reading 'protect')
at Object.<anonymous> (C:\Users\liams\dev\my-rest-server\src\routes\user.router.ts:8:46)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Module._compile (C:\Users\liams\dev\my-rest-server\node_modules\source-map-support\source-map-support.js:568:25)
at Module.m._compile (C:\Users\liams\AppData\Local\Temp\ts-node-dev-hook-8639111545614118.js:69:33)
at Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at require.extensions.<computed> (C:\Users\liams\AppData\Local\Temp\ts-node-dev-hook-8639111545614118.js:71:20)
at Object.nodeDevHook [as .ts] (C:\Users\liams\dev\my-rest-server\node_modules\ts-node-dev\lib\hook.js:63:13)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
[ERROR] 20:08:00 TypeError: Cannot read properties of undefined (reading 'protect')
知道我遗漏了什么吗?
编辑:您可以在存储库中看到它,而不是在这里发布我的代码的每一行:https://github.com/dotDone/my-rest-server/tree/auth
当您在用户控制器中使用它时,您的 RouteController 尚未定义。 (您的架构可以改进,但我只会尝试回答您的问题,只知道有更好的方法来组织所有这些) 尝试以下
将 UserRoutes 转为 class
import { Router } from 'express'
import * as userController from '../controllers/user.controller'
class UserRoutes {
constructor(routesController) {
this.userRouter: Router = Router();
this.routesController = routesController;
this.initRoutes();
}
initRoutes() {
userRouter.route('/').get(userController.getUsers).post(userController.createUser).put(userController.editUser).delete(userController.deleteUser)
userRouter.route('/me').get(this.routesController.protect, userController.getMe)
}
}
然后在您的 server.ts 中创建另一个函数,例如将其称为 initRoutes,您可以在其中执行类似操作
constructor() {
this.startServer().then(() => this.startControllers()).then(() => this.initRoutes()).catch(err => console.log(err))
}
...
initRoutes() {
this.userRoutes = new UserRoutes(this.routesController);
}